<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Benji 🍙</title>
    <description>The latest articles on DEV Community by Benji 🍙 (@benji011).</description>
    <link>https://dev.to/benji011</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F495832%2Fff591982-657d-4dac-a7c9-6773ed82bc59.png</url>
      <title>DEV Community: Benji 🍙</title>
      <link>https://dev.to/benji011</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/benji011"/>
    <language>en</language>
    <item>
      <title>My sudden episode to keep my virtualenv in check</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Thu, 08 Jan 2026 13:37:04 +0000</pubDate>
      <link>https://dev.to/benji011/my-sudden-episode-to-keep-my-virtualenv-in-check-3ah2</link>
      <guid>https://dev.to/benji011/my-sudden-episode-to-keep-my-virtualenv-in-check-3ah2</guid>
      <description>&lt;p&gt;I often run python scripts or commands outside of a virtualenv and this creates a problem with dependencies being installed globally, often left unchecked with wrong python versions. &lt;/p&gt;

&lt;p&gt;The solution is simple; If i'm not running a virtualenv anywhere then ideally I should get a warning message, &lt;strong&gt;loudly&lt;/strong&gt;. What i've ended up doing is creating a wrapper in my zsh config file that looks something like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Python wrapper to warn about uv venv&lt;/span&gt;
python&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
environment
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VIRTUAL_ENV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VIRTUAL_ENV&lt;/span&gt;&lt;span class="s2"&gt;/pyvenv.cfg"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"uv"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VIRTUAL_ENV&lt;/span&gt;&lt;span class="s2"&gt;/pyvenv.cfg"&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s2"&gt;33[1;31m"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2  &lt;span class="c"&gt;# Bold Red&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" ██╗    ██╗ █████╗ ██████╗ ███╗   ██╗██╗███╗   ██╗ ██████╗ ██╗"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" ██║    ██║██╔══██╗██╔══██╗████╗  ██║██║████╗  ██║██╔════╝ ██║"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" ██║ █╗ ██║███████║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║  ███╗██║"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" ██║███╗██║██╔══██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║   ██║╚═╝"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;" ╚███╔███╔╝██║  ██║██║  ██║██║ ╚████║██║██║ ╚████║╚██████╔╝ ██╗"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝╚═╝╚═╝  ╚═══╝ ╚═════╝  ╚═╝"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s2"&gt;33[1;33m UV virtual environment is NOT activated!&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s2"&gt;33[0m"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s2"&gt;33[0;36m Run: uv venv &amp;amp;&amp;amp; source .venv/bin/activate&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s2"&gt;33[0m"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class="k"&gt;return &lt;/span&gt;1
    &lt;span class="k"&gt;fi&lt;/span&gt;

    &lt;span class="c"&gt;# Execute the actual python command with all arguments&lt;/span&gt;
    &lt;span class="nb"&gt;command &lt;/span&gt;python &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above wrapper is specifically designed for uv-managed environments, checking not just if &lt;code&gt;$VIRTUAL_ENV&lt;/code&gt; is set but also validating that it's actually a &lt;code&gt;uv&lt;/code&gt; environment by grepping the &lt;code&gt;pyvenv.cfg&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Whenever i forget to activate my virtualenv, i'll get a massive ASCII art "WARNING!" banner in bold red, followed by instructions in yellow and cyan. It's obnoxious in the best possible way—you literally cannot miss it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfmayoqbrsx5yt0t270n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfmayoqbrsx5yt0t270n.png" alt="Execution of the python wrapper" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IMO the beauty in this is the Docker-esque approach so anytime I'm done with an environment, or I want to use a different Python version I can just deactivate and remove the current &lt;code&gt;.venv&lt;/code&gt; module and start again.&lt;/p&gt;

&lt;p&gt;Sometimes the best development tools are the ones that yell at you when you're about to do something really dumb or just out of impulse.&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>programming</category>
      <category>bash</category>
    </item>
    <item>
      <title>TIL about the command `nohup`</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Tue, 23 Dec 2025 15:48:03 +0000</pubDate>
      <link>https://dev.to/benji011/til-about-the-command-nohup-2h21</link>
      <guid>https://dev.to/benji011/til-about-the-command-nohup-2h21</guid>
      <description>&lt;p&gt;TIL about the command &lt;code&gt;nohup&lt;/code&gt;, which stands for "no hang up". It's a command that runs a process immune to hangup signals (SIGHUP).&lt;/p&gt;

&lt;p&gt;When you close your terminal or log out then the shell normally sends a SIGHUP signal to all running processes which terminates them. &lt;code&gt;nohup&lt;/code&gt; prevents this and allows processes to continue running even after you've close the terminal.&lt;/p&gt;

&lt;p&gt;I particularly needed this because I was locally running an &lt;code&gt;n8n&lt;/code&gt; workflow, and &lt;a href="https://hub.docker.com/r/n8nio/n8n" rel="noopener noreferrer"&gt;although there is a Docker container version&lt;/a&gt;, I didn't want the hassle in adding more containers that were already running and so if I could somehow find a way to run it as a daemon then that would be perfect. This was when I discovered nohup exists and is already installed by default on my macbook.&lt;/p&gt;

&lt;p&gt;To use it (like a background Docker container), you use the command similar to below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nohup command [arguments] &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means, run &lt;code&gt;command [arguments]&lt;/code&gt; and any stdout/stderr just gets shoved into &lt;code&gt;/dev/null&lt;/code&gt; (as my friend puts it, a rubbish bin where anything sent in is discarded ... like rafas opinions). The &lt;code&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; just means to redirect stderr to same place as stdout, and finally the last &lt;code&gt;&amp;amp;&lt;/code&gt; is to run in the background&lt;/p&gt;

&lt;p&gt;So in the end I ended up with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nohup n8n start &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reference: &lt;a href="https://www.digitalocean.com/community/tutorials/nohup-command-in-linux" rel="noopener noreferrer"&gt;https://www.digitalocean.com/community/tutorials/nohup-command-in-linux&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nohup</category>
      <category>linux</category>
      <category>webdev</category>
    </item>
    <item>
      <title>TIL you can output `aws ecr describe-images` as a table</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Mon, 09 Jun 2025 13:59:51 +0000</pubDate>
      <link>https://dev.to/benji011/til-you-can-output-aws-ecr-describe-images-as-a-table-3f4g</link>
      <guid>https://dev.to/benji011/til-you-can-output-aws-ecr-describe-images-as-a-table-3f4g</guid>
      <description>&lt;p&gt;Whenever I want to describe an image of a container image I pushed on AWS ECR i would see a JSON similar to below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ecr describe-images &lt;span class="nt"&gt;--repository-name&lt;/span&gt; &amp;lt;my-repo&amp;gt; &lt;span class="nt"&gt;--region&lt;/span&gt; &amp;lt;my-region&amp;gt; &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'sort_by(imageDetails,&amp;amp;imagePushedAt)[-1]'&lt;/span&gt;

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"registryId"&lt;/span&gt;: &lt;span class="s2"&gt;"*****"&lt;/span&gt;,
    &lt;span class="s2"&gt;"repositoryName"&lt;/span&gt;: &lt;span class="s2"&gt;"*******************"&lt;/span&gt;,
    &lt;span class="s2"&gt;"imageDigest"&lt;/span&gt;: &lt;span class="s2"&gt;"sha256:***************************************"&lt;/span&gt;,
    &lt;span class="s2"&gt;"imageTags"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"****"&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;,
    &lt;span class="s2"&gt;"imageSizeInBytes"&lt;/span&gt;: &lt;span class="k"&gt;**********&lt;/span&gt;,
    &lt;span class="s2"&gt;"imagePushedAt"&lt;/span&gt;: &lt;span class="s2"&gt;"***********************"&lt;/span&gt;,
    &lt;span class="s2"&gt;"imageManifestMediaType"&lt;/span&gt;: &lt;span class="s2"&gt;"***********************************************"&lt;/span&gt;,
    &lt;span class="s2"&gt;"artifactMediaType"&lt;/span&gt;: &lt;span class="s2"&gt;"***********************************************"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but with the suffix &lt;code&gt;--output table&lt;/code&gt; you can get a (IMO) much better layout&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ecr describe-images &lt;span class="nt"&gt;--repository-name&lt;/span&gt; &amp;lt;my-repo&amp;gt; &lt;span class="nt"&gt;--region&lt;/span&gt; &amp;lt;my-region&amp;gt; &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'sort_by(imageDetails,&amp;amp;imagePushedAt)[-1]'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;span class="nt"&gt;-------------------------------------------------------------------------------------------------------&lt;/span&gt;
|                                           DescribeImages                                            |
+-------------------------+---------------------------------------------------------------------------+
|  artifactMediaType      |  application/vnd.docker.container.image.v1+json                           |
|  imageDigest            |  sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  |
|  imageManifestMediaType |  application/vnd.docker.distribution.manifest.v2+json                     |
|  imagePushedAt          |  2025-01-01T00:00:00.000000+00:00                                         |
|  imageSizeInBytes       |  123456789                                                                |
|  registryId             |  000000000000                                                             |
|  repositoryName         |  my-repo                                                          |
+-------------------------+---------------------------------------------------------------------------+
&lt;span class="o"&gt;||&lt;/span&gt;                                             imageTags                                             &lt;span class="o"&gt;||&lt;/span&gt;
|+---------------------------------------------------------------------------------------------------+|
&lt;span class="o"&gt;||&lt;/span&gt;  my-tag                                                                                   &lt;span class="o"&gt;||&lt;/span&gt;
|+---------------------------------------------------------------------------------------------------+|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
      <category>ecr</category>
    </item>
    <item>
      <title>TIL you can apply git fixup automatically with git absorb</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Thu, 23 Jan 2025 10:47:55 +0000</pubDate>
      <link>https://dev.to/benji011/til-you-can-apply-git-fixup-automatically-with-git-absorb-44hk</link>
      <guid>https://dev.to/benji011/til-you-can-apply-git-fixup-automatically-with-git-absorb-44hk</guid>
      <description>&lt;p&gt;One thing to be clear is that &lt;a href="https://github.com/tummychow/git-absorb" rel="noopener noreferrer"&gt;git absorb&lt;/a&gt; is not an official command , at least not with version &lt;code&gt;2.39.2&lt;/code&gt; which is what I'm using.&lt;/p&gt;

&lt;p&gt;The idea is, if you've ever used git fixup you'll likely be aware you have to do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &amp;lt;my file&amp;gt;
git commit &lt;span class="nt"&gt;--edit&lt;/span&gt; &lt;span class="nt"&gt;--fixup&lt;/span&gt; &amp;lt;commit SHA&amp;gt;

&lt;span class="c"&gt;# And then rebase to keep your commit history clean and atomic&lt;/span&gt;
git rebase &lt;span class="nt"&gt;--autosquash&lt;/span&gt; &lt;span class="nt"&gt;--interactive&lt;/span&gt; origin/master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this guy does, is it will automatically find the correct commit SHA for you, and automatically if you append &lt;code&gt;--and-rebase&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The result is your commit history looks and reads like a book:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commit 2: Feature B
commit 1: Feature A
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commit 3: linting issue &lt;span class="k"&gt;for &lt;/span&gt;Feature A
commit 2: Fix bug &lt;span class="k"&gt;for &lt;/span&gt;failing &lt;span class="nb"&gt;test &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;Feature A
commit 2: Feature B
commit 1: Feature A
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>TIL how to profile `zsh` start time</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Thu, 16 Jan 2025 10:43:21 +0000</pubDate>
      <link>https://dev.to/benji011/til-how-to-profile-zsh-start-time-2bob</link>
      <guid>https://dev.to/benji011/til-how-to-profile-zsh-start-time-2bob</guid>
      <description>&lt;p&gt;Disclaimer: I'm heavily referencing from &lt;a href="https://stevenvanbael.com/profiling-zsh-startup" rel="noopener noreferrer"&gt;this blog post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tl:Dr&lt;/strong&gt;: Package managers like &lt;code&gt;nvm&lt;/code&gt;, &lt;code&gt;pyenv&lt;/code&gt; etc are initialized on startup and if you don't need one of them then just remove them from &lt;code&gt;zshrc&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;Everytime I load a new session on iterm I notice a significant wait time, so out of curiosity I googled around and discovered how to profile the &lt;code&gt;./zshrc&lt;/code&gt; file by using the below steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ &lt;span class="nb"&gt;time &lt;/span&gt;zsh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nb"&gt;exit
&lt;/span&gt;zsh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nb"&gt;exit  &lt;/span&gt;0.87s user 1.13s system 42% cpu 4.685 total
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command creates a temporary zsh subshell then measures the time it takes for the exit command to run within it. Finally, it prints the execution time to the console, which you see above is &lt;code&gt;4.6s&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can profile zsh by adding at the top  &lt;code&gt;zmodload zsh/zprof&lt;/code&gt; and &lt;code&gt;zprof&lt;/code&gt; at the bottom. &lt;code&gt;zprof&lt;/code&gt; is a built in profiler for &lt;code&gt;zsh&lt;/code&gt;, and when executed I see the output similar to below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;num  calls                &lt;span class="nb"&gt;time                       &lt;/span&gt;self            name
&lt;span class="nt"&gt;-----------------------------------------------------------------------------------&lt;/span&gt;
 1&lt;span class="o"&gt;)&lt;/span&gt;    6        2385.86   397.64   12.79%   2385.57   397.59   12.79%  __conda_activate
 2&lt;span class="o"&gt;)&lt;/span&gt;    4        1959.50   489.88   10.50%   1959.50   489.88   10.50%  git
 3&lt;span class="o"&gt;)&lt;/span&gt;   32        1940.77    60.65   10.40%   1940.77    60.65   10.40%  mcfly_prompt_command
 4&lt;span class="o"&gt;)&lt;/span&gt;    6        1512.94   252.16    8.11%   1512.94   252.16    8.11%  compdump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your output might show something else, as my personal laptop shows &lt;code&gt;nvm&lt;/code&gt; being the culprit, while my work laptop shows the above shows that &lt;code&gt;conda&lt;/code&gt; is taking up most of the time. &lt;a href="https://docs.conda.io/projects/conda/en/latest/user-guide/getting-started.html" rel="noopener noreferrer"&gt;Conda&lt;/a&gt; is a package manager tool similar to &lt;a href="https://github.com/pyenv/pyenv" rel="noopener noreferrer"&gt;pyenv&lt;/a&gt;, which I barely use and only had when experimenting with something months back. &lt;/p&gt;

&lt;p&gt;Anyway, looking through my &lt;code&gt;zshrc&lt;/code&gt; file I spot this to be the reason for the wait:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;125 &lt;span class="c"&gt;# &amp;gt;&amp;gt;&amp;gt; conda initialize &amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
126 &lt;span class="c"&gt;# !! Contents within this block are managed by 'conda init' !!&lt;/span&gt;
127 &lt;span class="nv"&gt;__conda_setup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="s1"&gt;'/Users/benji/miniconda3/bin/conda'&lt;/span&gt; &lt;span class="s1"&gt;'shell.zsh'&lt;/span&gt; &lt;span class="s1"&gt;'hook'&lt;/span&gt; 2&amp;gt; /dev/null&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
128 &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
&lt;/span&gt;129     &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$__conda_setup&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
130 &lt;span class="k"&gt;else
&lt;/span&gt;131     &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"/Users/benji/miniconda3/etc/profile.d/conda.sh"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
&lt;/span&gt;132         &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"/Users/benji/miniconda3/etc/profile.d/conda.sh"&lt;/span&gt;
133     &lt;span class="k"&gt;else
&lt;/span&gt;134         &lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/Users/benji/miniconda3/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
135     &lt;span class="k"&gt;fi
&lt;/span&gt;136 &lt;span class="k"&gt;fi
&lt;/span&gt;137 &lt;span class="nb"&gt;unset &lt;/span&gt;__conda_setup
138 &lt;span class="c"&gt;# &amp;lt;&amp;lt;&amp;lt; conda initialize &amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I'm fearful I'll need it again one day, I decide not to remove it and opted to comment it out instead. I then &lt;code&gt;source ~/.zshrc&lt;/code&gt; and see that the start time was reduced from 4.6s to 0.9s:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ &lt;span class="nb"&gt;time &lt;/span&gt;zsh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nb"&gt;exit
&lt;/span&gt;zsh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nb"&gt;exit  &lt;/span&gt;0.22s user 0.25s system 48% cpu 0.972 total
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>TIL that the `requests` library supports automatic retries with exponential backoff</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Fri, 06 Dec 2024 10:01:14 +0000</pubDate>
      <link>https://dev.to/benji011/til-that-the-requests-library-supports-automatic-retries-with-exponential-backoff-2b6d</link>
      <guid>https://dev.to/benji011/til-that-the-requests-library-supports-automatic-retries-with-exponential-backoff-2b6d</guid>
      <description>&lt;p&gt;You can use a customized Adapter and force several retries with an exponential backoff factor on all HTTP/HTTPS requests. See example below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;adapters&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;urllib3.util&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Retry&lt;/span&gt;

&lt;span class="c1"&gt;# Create a transport adapter with a custom retry strategy.
&lt;/span&gt;&lt;span class="n"&gt;retries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;backoff_factor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;status_forcelist&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;502&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;503&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;504&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;adapter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;adapters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HTTPAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Ensure adapter is used for both HTTP and HTTPS requests.
&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;adapter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;adapter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Testing the retry mechanism
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://httpbin.org/status/500&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns the error below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;RetryError: HTTPConnectionPool&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'httpbin.org'&lt;/span&gt;, &lt;span class="nv"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;80&lt;span class="o"&gt;)&lt;/span&gt;: Max retries exceeded with url: /status/500 &lt;span class="o"&gt;(&lt;/span&gt;Caused by ResponseError&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'too many 500 error responses'&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The unfortunate thing is that there doesn't seem to be a way to tell how many times the above mechanism has attempted to retry, only when all attempts have been exhausted&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/a/47475019/4477547" rel="noopener noreferrer"&gt;https://stackoverflow.com/a/47475019/4477547&lt;/a&gt;&lt;/p&gt;

</description>
      <category>requests</category>
      <category>retry</category>
      <category>python</category>
    </item>
    <item>
      <title>TIL how to see the entire commit column on GitLab using JS</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Wed, 27 Nov 2024 15:36:22 +0000</pubDate>
      <link>https://dev.to/benji011/til-how-to-see-the-entire-commit-column-on-gitlab-using-js-518m</link>
      <guid>https://dev.to/benji011/til-how-to-see-the-entire-commit-column-on-gitlab-using-js-518m</guid>
      <description>&lt;p&gt;This was quite a while back but I'm adding this here as a note-to-self thing.&lt;/p&gt;

&lt;p&gt;Whenever you open CI/CD &amp;gt; Pipelines on GitLab you might often see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvl8g2k9zmxkpjjll4r8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvl8g2k9zmxkpjjll4r8d.png" alt=" " width="800" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see the whole thing by opening up the dev console on your browser and changing some CSS to fix the styling. Another way you can  also see the entire column is by creating a new bookmark (on any page, it doesn't matter) and then edit the URL to be this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;javascript&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a.commit-sha.mr-0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;]);}&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div.container-limited&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2400px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a.ref-name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overflow&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unset&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;}})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgygw41y2b6q0t402jgp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgygw41y2b6q0t402jgp.png" alt=" " width="526" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So then when you click it, the table will resize to look like below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9wqmlu2i56256fwa8cu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9wqmlu2i56256fwa8cu.png" alt=" " width="800" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feyv8vj6njiyau8onfs22.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feyv8vj6njiyau8onfs22.png" alt=" " width="800" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>gitlab</category>
      <category>commit</category>
      <category>pipelines</category>
    </item>
    <item>
      <title>TIL you can create keyboard shortcuts to switch between a specific desktop</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Sun, 30 Jun 2024 13:51:32 +0000</pubDate>
      <link>https://dev.to/benji011/til-you-can-create-keyboard-shortcuts-to-switch-between-a-specific-desktop-1ic6</link>
      <guid>https://dev.to/benji011/til-you-can-create-keyboard-shortcuts-to-switch-between-a-specific-desktop-1ic6</guid>
      <description>&lt;p&gt;Normally on a mac, you can use the trackpad to swipe left or right to switch between a desktop. But you can add a shortcut to switch between desktop x instead of swiping multiple times, or swiping up to select one.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to do this
&lt;/h2&gt;

&lt;p&gt; &amp;gt; System preferences &amp;gt; Keyboard &amp;gt; Keyboard shortcuts &amp;gt; Mission Control &amp;gt; Tick the checkbox for mission control &amp;gt; Click the caret symbol on the left and check all the ones you want to add to a shortcut.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqr83ja1vj3jxiby61009.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqr83ja1vj3jxiby61009.png" alt=" " width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reference: &lt;a href="https://qiita.com/saboyutaka/items/d6cfd2a2b60f1a374d60#%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97%E3%82%92%E5%A2%97%E3%82%84%E3%81%97%E3%81%A6%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6" rel="noopener noreferrer"&gt;https://qiita.com/saboyutaka/items/d6cfd2a2b60f1a374d60#%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97%E3%82%92%E5%A2%97%E3%82%84%E3%81%97%E3%81%A6%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6&lt;/a&gt;&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>mac</category>
      <category>osx</category>
    </item>
    <item>
      <title>TIL you can restore deleted files from a commit and then apply a git fixup to update the changes of that commit instead.</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Fri, 17 May 2024 09:53:00 +0000</pubDate>
      <link>https://dev.to/benji011/til-you-can-restore-deleted-files-from-a-commit-and-then-apply-a-git-fixup-to-update-the-changes-of-that-commit-instead-5f0k</link>
      <guid>https://dev.to/benji011/til-you-can-restore-deleted-files-from-a-commit-and-then-apply-a-git-fixup-to-update-the-changes-of-that-commit-instead-5f0k</guid>
      <description>&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git checkout [previous_commit_hash]^ -- [file_path]&lt;/code&gt;&lt;br&gt;
a. The ^just specifies the parent commit of the previous commit hash where the file shouldn't have been deleted&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(optional) Edit your file if you want to include any change in the commit instead &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git commit --edit --fixup [previous_commit_hash]&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rebase with autosquash so you apply the fixup commit to the previous commit hash &lt;code&gt;git rebase --autosquash --interactive origin/master&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Force push (with lease) to your feature branch  &lt;code&gt;git push origin [your_branch] --force-with-lease&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Any changes in the previous commit are just retained as normal&lt;/p&gt;

&lt;p&gt;The other way you can do this (if its the latest commit) is to just &lt;code&gt;git reset HEAD~1&lt;/code&gt; to undo those changes, checkout the file that was deleted so its no longer included, then commit again with the same commit message. You'd still need to force push though since you're rewriting the commit history&lt;/p&gt;

</description>
    </item>
    <item>
      <title>TIL you can re-order your commit history through rebase -i</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Tue, 13 Jun 2023 14:42:53 +0000</pubDate>
      <link>https://dev.to/benji011/til-you-can-re-order-your-commit-history-through-rebase-i-35kn</link>
      <guid>https://dev.to/benji011/til-you-can-re-order-your-commit-history-through-rebase-i-35kn</guid>
      <description>&lt;p&gt;Suppose you have a commit history like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commit 5: Refactor code &lt;span class="k"&gt;for &lt;/span&gt;better performance
commit 4: Add new feature: user authentication
commit 3: Fix typo &lt;span class="k"&gt;in &lt;/span&gt;README file
commit 2: Update documentation with usage instructions
commit 1: Initial commit with project setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then you have a new commit "Another README for user authentication" that should go after commit 4 and before commit 5:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commit 6: Another README &lt;span class="k"&gt;for &lt;/span&gt;user authentication
commit 5: Refactor code &lt;span class="k"&gt;for &lt;/span&gt;better performance
commit 4: Add new feature: user authentication
commit 3: Fix typo &lt;span class="k"&gt;in &lt;/span&gt;README file
commit 2: Update documentation with usage instructions
commit 1: Initial commit with project setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then using &lt;code&gt;git rebase -i HEAD~x&lt;/code&gt; (where x represents the number of commits you want to include in the rebase) you can re-order the commit history with relative ease, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This opens up your editor as usual&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pick 6: Another README &lt;span class="k"&gt;for &lt;/span&gt;user authentication
pick 5: Refactor code &lt;span class="k"&gt;for &lt;/span&gt;better performance
pick 4: Add new feature: user authentication
pick 3: Fix typo &lt;span class="k"&gt;in &lt;/span&gt;README file
pick 2: Update documentation with usage instructions
pick 1: Initial commit with project setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And moving the commit to where you want&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pick 5: Refactor code &lt;span class="k"&gt;for &lt;/span&gt;better performance
pick 6: Another README &lt;span class="k"&gt;for &lt;/span&gt;user authentication
pick 4: Add new feature: user authentication
pick 3: Fix typo &lt;span class="k"&gt;in &lt;/span&gt;README file
pick 2: Update documentation with usage instructions
pick 1: Initial commit with project setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save then close the editor and it's done. Confirm in your git log before pushing remotely&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;commit 6: Refactor code &lt;span class="k"&gt;for &lt;/span&gt;better performance
commit 5: Another README &lt;span class="k"&gt;for &lt;/span&gt;user authentication
commit 4: Add new feature: user authentication
commit 3: Fix typo &lt;span class="k"&gt;in &lt;/span&gt;README file
commit 2: Update documentation with usage instructions
commit 1: Initial commit with project setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>TIL you can convert media file extensions with ffmpeg</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Sun, 28 May 2023 12:30:26 +0000</pubDate>
      <link>https://dev.to/benji011/til-you-can-convert-media-file-extensions-with-ffmpeg-1ibc</link>
      <guid>https://dev.to/benji011/til-you-can-convert-media-file-extensions-with-ffmpeg-1ibc</guid>
      <description>&lt;p&gt;You can convert a video clips file extension using &lt;a href="https://ffmpeg.org/" rel="noopener noreferrer"&gt;ffmpeg&lt;/a&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; chill.mp4 chill.wav
&lt;span class="nv"&gt;$ &lt;/span&gt;ll
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt;  1 hello  world  84317363 21 Jun  2022 chill.mp4
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt;  1 hello  world  49074254 28 May 13:13 chill.wav
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also play directly from the terminal (which opens in a new window)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ffplay chill.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje49ta4rsbetlrntma9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje49ta4rsbetlrntma9b.png" alt="Streaming a video file using ffplay" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And probably the most useful I found, which is to convert a video clip to a &lt;code&gt;.gif&lt;/code&gt; for PRs/MRs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;.mov &lt;span class="nt"&gt;-s&lt;/span&gt; 600x400 &lt;span class="nt"&gt;-pix_fmt&lt;/span&gt; rgb24 &lt;span class="nt"&gt;-r&lt;/span&gt; 10 &lt;span class="nt"&gt;-f&lt;/span&gt; gif - | gifsicle &lt;span class="nt"&gt;--optimize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3 &lt;span class="nt"&gt;--delay&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; out.gif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Notes on the arguments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-r 10&lt;/code&gt; tells ffmpeg to reduce the frame rate from 25 fps to 10&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-s 600x400&lt;/code&gt; tells ffmpeg the max-width and max-height&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--delay=3&lt;/code&gt; tells gifsicle to delay 30ms between each gif&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--optimize=3&lt;/code&gt; requests that gifsicle use the slowest/most file-size optimization &lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;(full credits for this one go to this &lt;a href="https://gist.github.com/dergachev/4627207#instructions" rel="noopener noreferrer"&gt;README.md&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>ffmpeg</category>
      <category>convert</category>
      <category>file</category>
      <category>extensions</category>
    </item>
    <item>
      <title>TIL you can trick Mypys typechecker using typing.cast</title>
      <dc:creator>Benji 🍙</dc:creator>
      <pubDate>Wed, 24 May 2023 10:29:30 +0000</pubDate>
      <link>https://dev.to/benji011/til-you-can-trick-mypys-typechecker-using-typingcast-218b</link>
      <guid>https://dev.to/benji011/til-you-can-trick-mypys-typechecker-using-typingcast-218b</guid>
      <description>&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;You might have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# models.py
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModelQuerySet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QuerySet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
    &lt;span class="c1"&gt;# ...
&lt;/span&gt;
&lt;span class="c1"&gt;# views.py
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyView&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_queryset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;QuerySet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# ...
&lt;/span&gt;        &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stuff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;# ...
&lt;/span&gt;        &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;need_other_stuff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_other_stuff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And when you run Mypy it will spit out the below error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Incompatible types &lt;span class="k"&gt;in &lt;/span&gt;assignment &lt;span class="o"&gt;(&lt;/span&gt;expression has &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s2"&gt;"_QuerySet[MyModel, MyModel]"&lt;/span&gt;, variable has &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s2"&gt;"MyModelQuerySet[MyModel]"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;[&lt;/span&gt;assignment]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This error points to the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ...
&lt;/span&gt;&lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stuff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# ...
&lt;/span&gt;&lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;need_other_stuff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_other_stuff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You &lt;em&gt;could&lt;/em&gt; explicitly type annotate them but then you'll meet another error&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Name &lt;span class="s2"&gt;"qs"&lt;/span&gt; already defined on line x 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;Python 3.10 has the cast function, and you wrap the above examples like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cast&lt;/span&gt;
&lt;span class="c1"&gt;# ...
&lt;/span&gt;&lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyModelQuerySet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stuff&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="c1"&gt;# ...
&lt;/span&gt;&lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyModelQuerySet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;need_other_stuff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_other_stuff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cast function essentially just takes in a type as the first parameter, your value as the 2nd and simply returns the 2nd one unchanged.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .../lib/python3.10/typing.py
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;typ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Cast a value to a type.

    This returns the value unchanged.  To the type checker this
    signals that the return value has the designated type, but at
    runtime we intentionally don&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t check anything (we want this
    to be as fast as possible).
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A word of caution:&lt;/p&gt;

&lt;p&gt;Although doing this is a way to inform mypy your intent it doesn't guarantee that the assigned value will be of the correct type at runtime.&lt;/p&gt;

</description>
      <category>python</category>
      <category>typechecking</category>
      <category>typeannotating</category>
      <category>mypy</category>
    </item>
  </channel>
</rss>
