Yes, the use of macros is not always justified in the examples, because Python is quite expressive already.
However, the ability to have macros is orthogonal with the feature set of the language. What is interesting is the ability to inspect and modify a Python AST.
Of course, meta-programming is a way to integrate otherwise absent features of a language as-if they were built-in.
Python is sufficiently dynamic that most things can be done using existing facilities, like reflection and metaobjects (the @case example, as you mention).
But there is a difference between using those facilites at runtime and producing some code at macro-expansion time (this might be relevant for Cython, for example).
You can, for example, define a domain-specific language that is directly translated as Python, and not interpreted like an API-based representation would. You can even apply custom type checking for that DSL.
Or, you could analyze an existing python source code and produce a translation in another language without having to reimplement a parser (see the Python-to-Javascript example, or Common-Lisp's Parenscript).
However, the ability to have macros is orthogonal with the feature set of the language. What is interesting is the ability to inspect and modify a Python AST.
Of course, meta-programming is a way to integrate otherwise absent features of a language as-if they were built-in. Python is sufficiently dynamic that most things can be done using existing facilities, like reflection and metaobjects (the @case example, as you mention).
But there is a difference between using those facilites at runtime and producing some code at macro-expansion time (this might be relevant for Cython, for example).
You can, for example, define a domain-specific language that is directly translated as Python, and not interpreted like an API-based representation would. You can even apply custom type checking for that DSL.
Or, you could analyze an existing python source code and produce a translation in another language without having to reimplement a parser (see the Python-to-Javascript example, or Common-Lisp's Parenscript).