<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[OpenDIRO Opinion Zone]]></title><description><![CDATA[OpenDIRO Opinion Zone]]></description><link>https://blog.opendiro.io</link><generator>RSS for Node</generator><lastBuildDate>Tue, 14 Apr 2026 03:27:00 GMT</lastBuildDate><atom:link href="https://blog.opendiro.io/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Goals for Improving Python]]></title><description><![CDATA[Python is a great language. It's simple enough for learning/scratch projects; and powerful enough to make complex solutions.
However, nothing is perfect. Our worlds are evolving at an exponential rate. The Javascript community has an answer to everyt...]]></description><link>https://blog.opendiro.io/goals-for-improving-python</link><guid isPermaLink="true">https://blog.opendiro.io/goals-for-improving-python</guid><category><![CDATA[Python]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[Python 3]]></category><dc:creator><![CDATA[Anthony King]]></dc:creator><pubDate>Tue, 10 May 2022 22:41:10 GMT</pubDate><content:encoded><![CDATA[<p>Python is a great language. It's simple enough for learning/scratch projects; and powerful enough to make complex solutions.</p>
<p>However, nothing is perfect. Our worlds are evolving at an exponential rate. The Javascript community has an answer to everything, introducing features + new concepts as they shoulder the responsibility of being a language for every stack.
To rub more salt in, key python tools are now being written in Javascript, due to its size, flexibility; but most importantly, the insane power that Typescript provides.</p>
<p>There are 3 main areas in Python that I'd like to improve, and I think they're features the community will appreciate.</p>
<p>The goal is to have PEPs prepared where needed in the next few months, with everything detailed here finished ready for the Python 3.12 release.</p>
<p><em>Disclaimer: While I've been an avid follower of Python Core, it's rare I get directly involved. Know, though, it has been a lack of time + motivation that has kept me away.</em></p>
<h2 id="heading-tagged-templates">Tagged Templates</h2>
<p>We all rejoiced with the introduction of <code>f-strings</code>; however they don't go far enough.</p>
<p>For those that don't know what a Tagged Template is, it's effectively a custom <code>f-string</code>.
The main use case here is for providing a more native form of escaping.</p>
<h3 id="heading-uses">Uses</h3>
<h4 id="heading-escaping">Escaping</h4>
<pre><code class="lang-py"><span class="hljs-meta">&gt;&gt;&gt; </span>evil_href = <span class="hljs-string">'#"&gt;&lt;s&gt;exit();&lt;/s&gt;&lt;"'</span>
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-string">f'&lt;a href="<span class="hljs-subst">{evil_href}</span>"&gt;Link&lt;/a&gt;'</span>
<span class="hljs-string">'&lt;a href="#"&gt;&lt;s&gt;exit();&lt;/s&gt;&lt;""&gt;Link&lt;/a&gt;'</span>
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-string">f'&lt;a href="<span class="hljs-subst">{html.escape(some_link)}</span>"&gt;Link&lt;/a&gt;'</span>
<span class="hljs-string">'&lt;a href="&amp;quot;&amp;gt;&amp;lt;s&amp;gt;exit();&amp;lt;/s&amp;gt;&amp;lt;&amp;quot;"&gt;Link&lt;/a&gt;'</span>

<span class="hljs-comment"># Proposed syntax (backticks)</span>
<span class="hljs-meta">&gt;&gt;&gt; </span> html`&lt;a href=<span class="hljs-string">"{evil_href}"</span>&gt;Link&lt;/a&gt;`
<span class="hljs-string">'&lt;a href="&amp;quot;&amp;gt;&amp;lt;s&amp;gt;exit();&amp;lt;/s&amp;gt;&amp;lt;&amp;quot;"&gt;Link&lt;/a&gt;'</span>
</code></pre>
<h4 id="heading-new-gen-logging">New gen logging</h4>
<pre><code class="lang-py"><span class="hljs-meta">&gt;&gt;&gt; </span>amount = <span class="hljs-number">10</span>
<span class="hljs-meta">&gt;&gt;&gt; </span>LOG.warning(<span class="hljs-string">f"<span class="hljs-subst">{amount=}</span>"</span>)
<span class="hljs-meta">&gt;&gt;&gt; </span>LOG.warning`{amount=}`
<span class="hljs-comment"># logs `amount=10</span>
</code></pre>
<p>consider the potential for lazy logging by deferring analysis.
In the first version, the string is evaluated before <code>warning</code> is called.
however in the second, there's potential to defer the evaluation until the <code>LOG.warning</code> actually tries to emit the message, as <code>LOG.warning</code> uses the expression itself.</p>
<h3 id="heading-implementation-details">Implementation details</h3>
<p><em>Disclaimer: while I have walked the CPython codebase, I'm not familiar with all the related workings</em></p>
<p>The structure could be similar to that of <code>string.Formatter.parse</code>; however to align with the newer <code>f-string</code> syntax (which has an extra layer ontop of the mini-language).</p>
<p>An alternate is an iterator that emits strings + fields.
The iterator determines the underlying grammar (usually <code>f-string</code> or the Format Mini-Language).</p>
<pre><code class="lang-py"><span class="hljs-comment"># Simplest form, provide utilities to guide development.</span>
<span class="hljs-comment"># Migration for user is simple, `html("")` to `html`` `</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Element</span>:</span>
  is_expression: bool
  code: Code  <span class="hljs-comment"># reference to code object of the literal or expression</span>
  evaluate: (self, ns) -&gt; str  <span class="hljs-comment"># evaluates the code expression</span>


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">html</span>(<span class="hljs-params">template: str, ns={}</span>):</span>
  string_parts = []
  <span class="hljs-keyword">for</span> element <span class="hljs-keyword">in</span> process(template):
    evaluated = element.evaluate(ns=ns)
    <span class="hljs-keyword">if</span> element.is_expression:
      final_elements.append(escape(evaluated))
    <span class="hljs-keyword">else</span>:
       final_elements.append(evaluated)
  <span class="hljs-keyword">return</span> <span class="hljs-string">''</span>.join(string_parts)
</code></pre>
<p>Without knowing the optimisations taken for f-string, this "dumb" approach might not be feasible.</p>
<h2 id="heading-structural-types-manipulations">Structural Types + Manipulations</h2>
<p>Python is rife with uses of meta-programming to subtly adjust how classes can be used. Django, dataclasses, attrs, pydantic.
Just because a <code>metaclass</code> isn't used, doesn't mean it isn't meta-programming.</p>
<p>For something so conceptually simple, not many understand how the data model in python works. This is fine, you really don't need to know it.
For whatever reason, Metaclasses don't have much support in <code>mypy</code> or <code>pyright</code>. Instead, they fallback onto using Quirks within their implementations for popular libraries.</p>
<p>My aim is 2 fold:</p>
<ul>
<li><p>document how the objects used to build a class tie in together, and write a mypy plugin to codify the assumptions. The goal here is to get to a point where the class body written by the user is exposed to <code>mcls.__new__</code>, which can then output a class with a different body</p>
</li>
<li><p>mypy plugin to demo using Dictionaries directly to do structure manipulation (like Typescript Mapped Types)</p>
</li>
</ul>
<p>After those 2 aims are done, I will work with members of Pyright + Mypy to see if these are appropriate solutions, and how we can iterate from there.</p>
<h3 id="heading-structure-remapping">Structure Remapping</h3>
<p>To aid with documenting the shape of data, be it class structures or your domain data, we need to be able to preserve context.</p>
<h2 id="heading-a-new-typing-library">A new Typing library</h2>
<p>Much of how the typing library works is actually somewhat voodoo; a lot is hidden from us, and exists only as Documentation due to much of the usage being within the type-analysers (mypy, pyright) themselves.
This makes deviating from the basics pretty difficult when compared to a feature-rich language, such as Typescript.</p>
<p>A new library will allow for a different take on Typing within Python:</p>
<ul>
<li>The typing library was designed not designed for much runtime use, primarily for debugging</li>
<li>A focus on "Structures" to define shapes/behaviour will allow features to be iterated on without being tied to Python/mypy/pyright (Avoid SpecialForm)</li>
<li>A focus on building tools for use within the runtime, with an aim for doing more with Macros down the road</li>
<li>It's a chance to fully learn + document how types <em>actually</em> function, and how implementations differ</li>
</ul>
<h2 id="heading-summary">Summary</h2>
<p>It's going to be a busy year over at OpenDIRO; but I hope that once the Discussions are opened up, we can iterate quickly to get community feedback.</p>
<p>Have a good one, and stay tuned for what we'll be doing to extend Pulumi.</p>
]]></content:encoded></item></channel></rss>