{"id":862,"date":"2023-08-12T22:54:44","date_gmt":"2023-08-12T22:54:44","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=862"},"modified":"2023-08-23T16:20:23","modified_gmt":"2023-08-23T16:20:23","slug":"type-hinting-static-type-checking-mypy","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/","title":{"rendered":"Type Hinting and Static Type Checking with Mypy"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Brief Overview<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Type hinting, an essential feature in modern programming, enables developers to explicitly annotate variables, functions, and more with the expected data types. Not only does it make the code more readable, but it also facilitates error detection, code refactoring, and enhances IDE features like autocompletion. In a dynamically-typed language like Python, type hinting can bridge the gap between ease of use and rigorous code structure.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Introducing Mypy<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Mypy is a powerful static type checker for Python, allowing developers to enforce type constraints at compile time rather than at runtime. By using Mypy, teams can uncover potential bugs earlier in the development process and ensure that the types used across a codebase are consistent and accurately documented. With its robust set of features and adherence to PEP 484, Mypy has become the go-to solution for many developers wishing to take advantage of type hinting in Python.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Target Audience<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This article is crafted for experienced developers who already have a fundamental understanding of Python and are looking to delve deeper into advanced type hinting and static type checking. Whether you&#8217;re working on a large-scale project that demands strict type enforcement or simply looking to adopt best practices in your code, this comprehensive guide to using Mypy will provide you with the practical knowledge and examples you need.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By the end of this article, you will have a clear understanding of how Mypy can be leveraged in real-world scenarios to write cleaner, more maintainable code. Prepare to explore the next level of Python development, where type hinting meets practical implementation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why Use Mypy for Type Checking<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Benefits of Type Checking<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Type checking, the process of verifying the data types of variables and expressions in a program, is vital for maintaining code quality and reducing the risk of runtime errors. Here&#8217;s a closer look at some of the key benefits:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Early Error Detection<\/strong>: By verifying types at compile time, developers can catch errors early in the development process, reducing the chance of unexpected issues in production.<\/li>\n\n\n\n<li><strong>Improved Code Readability<\/strong>: Type annotations act as a form of documentation, making it easier for developers to understand the expected input and output types of functions and methods.<\/li>\n\n\n\n<li><strong>Enhanced Collaboration<\/strong>: In a team environment, type checking ensures that everyone understands the expected data structures, leading to more consistent code across different parts of a project.<\/li>\n\n\n\n<li><strong>Facilitating Refactoring<\/strong>: Type hints aid in the refactoring process by providing clear constraints on how data should flow through the code, making changes safer and more controlled.<\/li>\n\n\n\n<li><strong>Integration with IDEs<\/strong>: Many Integrated Development Environments (IDEs) can use type annotations to provide intelligent autocompletion and error highlighting, improving the overall development experience.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Why Mypy<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Mypy stands out in the realm of static type checking for several reasons:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Adherence to Standards<\/strong>: Mypy follows the PEP 484, PEP 526, and other related PEP standards, ensuring compatibility and best practices in type hinting.<\/li>\n\n\n\n<li><strong>Incremental Adoption<\/strong>: You can introduce Mypy gradually into an existing codebase, checking parts of the program as you go, making the transition smoother and less disruptive.<\/li>\n\n\n\n<li><strong>Rich Type System<\/strong>: Mypy supports a wide variety of type constructs, including generics, unions, and custom types, enabling more precise type definitions.<\/li>\n\n\n\n<li><strong>Performance<\/strong>: By reducing the need for runtime type checking, Mypy can improve the overall performance of a Python application.<\/li>\n\n\n\n<li><strong>Extensibility<\/strong>: Mypy&#8217;s plugin system allows developers to write custom plugins to enforce specific rules or behaviors, making it adaptable to various project needs.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">In essence, Mypy brings a level of rigor and precision to Python development that aligns with the expectations of modern software engineering. Its flexibility, robust feature set, and alignment with Python&#8217;s official type hinting standards make it an invaluable tool for developers aiming to produce high-quality, maintainable code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Advanced Type Hinting Techniques<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In the world of Python programming, Mypy provides a rich set of tools for implementing advanced type hinting. This section delves into some of the more sophisticated techniques you can leverage to make your code more robust and maintainable.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Generic Types<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Generic types enable you to write flexible and reusable code by defining functions or classes that can work with different types. Mypy supports generics, allowing you to create type-safe code.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> typing <span class=\"hljs-keyword\">import<\/span> List, Generic, TypeVar\n\nT = TypeVar(<span class=\"hljs-string\">'T'<\/span>)\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Container<\/span><span class=\"hljs-params\">(Generic&#91;T])<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, items: List&#91;T])<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n        self.items = items<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This example demonstrates a generic <code>Container<\/code> class that can hold items of any type.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using Protocols<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Protocols are a powerful feature that allows you to define structural types. Unlike regular classes, protocols focus on what an object can do (methods and attributes) rather than what it is.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> typing <span class=\"hljs-keyword\">import<\/span> Protocol\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Drawable<\/span><span class=\"hljs-params\">(Protocol)<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">draw<\/span><span class=\"hljs-params\">(self)<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n        ...\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">render<\/span><span class=\"hljs-params\">(item: Drawable)<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n    item.draw()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">With this code, any class with a <code>draw<\/code> method matches the <code>Drawable<\/code> protocol, allowing for more flexible and extendable code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Type Aliases<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Type aliases help make complex type hints more readable and manageable by creating shorthand notations for them.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> typing <span class=\"hljs-keyword\">import<\/span> List, Dict\n\nPerson = Dict&#91;str, str]\nPeople = List&#91;Person]\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">show_people<\/span><span class=\"hljs-params\">(people: People)<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n    ...<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Here, <code>Person<\/code> and <code>People<\/code> are type aliases, simplifying the function signature.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Callable Types<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Callable types let you describe the function signatures, which is useful when passing functions as arguments.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> typing <span class=\"hljs-keyword\">import<\/span> Callable\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">execute<\/span><span class=\"hljs-params\">(func: Callable&#91;&#91;int, int], int], x: int, y: int)<\/span> -&gt; int:<\/span>\n    <span class=\"hljs-keyword\">return<\/span> func(x, y)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This code specifies that the <code>func<\/code> parameter must be a callable object that takes two integers and returns an integer.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Newtype<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>NewType<\/code> function in Mypy creates distinct types that are based on existing types but are considered different by the type checker.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> typing <span class=\"hljs-keyword\">import<\/span> NewType\n\nUserId = NewType(<span class=\"hljs-string\">'UserId'<\/span>, int)\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">get_user<\/span><span class=\"hljs-params\">(user_id: UserId)<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n    ...<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">With <code>UserId<\/code>, you can ensure that only variables explicitly typed as <code>UserId<\/code> are acceptable, even though it&#8217;s based on the <code>int<\/code> type.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">An Example<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Each of these advanced type hinting techniques provides unique advantages in code structuring and validation. Here&#8217;s a more complex example that combines several of these concepts:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> typing <span class=\"hljs-keyword\">import<\/span> List, Protocol, TypeVar, Generic\n\nT = TypeVar(<span class=\"hljs-string\">'T'<\/span>)\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Drawable<\/span><span class=\"hljs-params\">(Protocol)<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">draw<\/span><span class=\"hljs-params\">(self)<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n        ...\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Container<\/span><span class=\"hljs-params\">(Generic&#91;T])<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, items: List&#91;T])<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n        self.items = items\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">render_container<\/span><span class=\"hljs-params\">(container: Container&#91;Drawable])<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n    <span class=\"hljs-keyword\">for<\/span> item <span class=\"hljs-keyword\">in<\/span> container.items:\n        item.draw()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this code, we&#8217;ve defined a generic <code>Container<\/code> class, a <code>Drawable<\/code> protocol, and a <code>render_container<\/code> function that takes a container of drawable items.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Integrating Mypy with Development Tools<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Mypy&#8217;s value extends beyond mere code validation; it can be woven into various stages of the development workflow. By integrating Mypy with different tools, developers can ensure that type checking is an essential part of the code development, review, and deployment process.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Integrating with IDEs<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Mypy can be integrated into popular Integrated Development Environments (IDEs) to provide real-time type checking as you write code. Here&#8217;s how you can set up Mypy with some commonly used IDEs:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>PyCharm<\/strong>: PyCharm supports Mypy out-of-the-box. Simply go to <code><strong>Preferences &gt; Editor &gt; Inspections &gt; Python &gt; Mypy<\/strong><\/code>, and enable the Mypy inspection.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Visual Studio Code<\/strong>: Install the Mypy extension and configure it in the settings (<code><strong>.vscode\/settings.json<\/strong><\/code>). Add the following configuration:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json\">{\n  <span class=\"hljs-attr\">\"python.linting.mypyEnabled\"<\/span>: <span class=\"hljs-literal\">true<\/span>,\n  <span class=\"hljs-attr\">\"python.linting.mypyPath\"<\/span>: <span class=\"hljs-string\">\"&lt;path_to_mypy&gt;\"<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">These integrations provide immediate feedback within the editor, highlighting potential type errors as you type.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Mypy with Git Hooks<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Integrating Mypy with Git Hooks ensures that code committed to your repository meets the defined type constraints. Here&#8217;s how to set up a pre-commit hook with Mypy:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Install pre-commit<\/strong>: Run <code><strong>pip install pre-commit<\/strong><\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Create a <code>.pre-commit-config.yaml<\/code><\/strong> file with the following content:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml\"><span class=\"hljs-attr\">repos:<\/span>\n<span class=\"hljs-bullet\">-<\/span>   <span class=\"hljs-attr\">repo:<\/span> <span class=\"hljs-string\">https:\/\/github.com\/pre-commit\/mirrors-mypy<\/span>\n    <span class=\"hljs-attr\">rev:<\/span> <span class=\"hljs-string\">v0.910<\/span> <span class=\"hljs-comment\"># or the version you want<\/span>\n    <span class=\"hljs-attr\">hooks:<\/span>\n    <span class=\"hljs-bullet\">-<\/span>   <span class=\"hljs-attr\">id:<\/span> <span class=\"hljs-string\">mypy<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><strong>Install the Git Hook<\/strong>: Run <code><strong>pre-commit install<\/strong><\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, Mypy will run automatically on each <code><strong>git commit<\/strong><\/code>, checking the staged files.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Continuous Integration (CI) Setup<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Continuous Integration (CI) systems like Jenkins, GitLab CI, and GitHub Actions can be configured to run Mypy as part of the build process.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, in a GitHub Actions workflow, you can add the following step:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"YAML\" data-shcb-language-slug=\"yaml\"><span><code class=\"hljs language-yaml\"><span class=\"hljs-bullet\">-<\/span> <span class=\"hljs-attr\">name:<\/span> <span class=\"hljs-string\">Run<\/span> <span class=\"hljs-string\">Mypy<\/span>\n  <span class=\"hljs-attr\">run:<\/span> <span class=\"hljs-string\">|\n    pip install mypy\n    mypy .<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">YAML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">yaml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This step ensures that Mypy checks are performed on every push or pull request, making type checking a fundamental part of your build pipeline.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Real-world Example<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In this section, we&#8217;ll dive into a real-world example that demonstrates the practical application of Mypy for type hinting and static type checking in a Python project. This example covers a common problem faced by developers and offers a solution that leverages the power of Mypy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Problem Statement<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine you are working on a system that manages a library of books. You need to define a set of classes and functions to handle books, authors, and library transactions. The requirements are as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Define classes for <code>Book<\/code> and <code>Author<\/code>.<\/li>\n\n\n\n<li>Create a <code>Library<\/code> class that can add books, remove books, and list all books.<\/li>\n\n\n\n<li>Implement type-safe functions without compromising readability and flexibility.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The challenge lies in maintaining clear and consistent type definitions across these different components.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Solution<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s dive into the solution, implementing the above requirements with proper type hinting and using Mypy for type checking.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Define Classes for Book and Author<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ll start by defining the <code>Author<\/code> and <code>Book<\/code> classes:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> typing <span class=\"hljs-keyword\">import<\/span> List\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Author<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, name: str)<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n        self.name = name\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Book<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self, title: str, authors: List&#91;Author])<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n        self.title = title\n        self.authors = authors<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Create a Library Class<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we&#8217;ll define the <code>Library<\/code> class, handling the addition, removal, and listing of books:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Library<\/span>:<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span><span class=\"hljs-params\">(self)<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n        self.books: List&#91;Book] = &#91;]\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">add_book<\/span><span class=\"hljs-params\">(self, book: Book)<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n        self.books.append(book)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">remove_book<\/span><span class=\"hljs-params\">(self, book: Book)<\/span> -&gt; <span class=\"hljs-keyword\">None<\/span>:<\/span>\n        self.books.remove(book)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">list_books<\/span><span class=\"hljs-params\">(self)<\/span> -&gt; List&#91;Book]:<\/span>\n        <span class=\"hljs-keyword\">return<\/span> self.books<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Demonstrate Usage<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of how these classes and functions might be used in a program:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-comment\"># Create authors<\/span>\nauthor1 = Author(<span class=\"hljs-string\">\"George Orwell\"<\/span>)\nauthor2 = Author(<span class=\"hljs-string\">\"Aldous Huxley\"<\/span>)\n\n<span class=\"hljs-comment\"># Create books<\/span>\nbook1 = Book(<span class=\"hljs-string\">\"1984\"<\/span>, &#91;author1])\nbook2 = Book(<span class=\"hljs-string\">\"Brave New World\"<\/span>, &#91;author2])\n\n<span class=\"hljs-comment\"># Create library<\/span>\nlibrary = Library()\nlibrary.add_book(book1)\nlibrary.add_book(book2)\n\n<span class=\"hljs-comment\"># List books<\/span>\n<span class=\"hljs-keyword\">for<\/span> book <span class=\"hljs-keyword\">in<\/span> library.list_books():\n    print(book.title)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Running Mypy on this code ensures that all the type annotations are correct, and the relationships between books, authors, and the library are consistently defined.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This real-world example illustrates how Mypy and proper type hinting can be applied to a practical scenario. By using type hints and validating the code with Mypy, we create a robust solution that is both easy to understand and maintain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This approach enforces a contract between different parts of the code, ensuring that developers adhere to expected data structures and function signatures. It illustrates the power of Mypy as not just a type-checking tool but an integral part of writing clean, efficient, and error-free Python code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Brief Overview Type hinting, an essential feature in modern programming, enables developers to explicitly annotate variables, functions, and more with the expected data types. Not only does it make the code more readable, but it also facilitates error detection, code refactoring, and enhances IDE features like autocompletion. In a dynamically-typed language like Python, type [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4,6],"tags":[],"class_list":["post-862","post","type-post","status-publish","format-standard","category-programming-languages","category-python","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Type Hinting and Static Type Checking with Mypy<\/title>\n<meta name=\"description\" content=\"Mypy is a powerful static type checker for Python, allowing developers to enforce type constraints at compile time rather than at runtime.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Type Hinting and Static Type Checking with Mypy\" \/>\n<meta property=\"og:description\" content=\"Mypy is a powerful static type checker for Python, allowing developers to enforce type constraints at compile time rather than at runtime.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-08-12T22:54:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-08-23T16:20:23+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/type-hinting-static-type-checking-mypy\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/type-hinting-static-type-checking-mypy\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"Type Hinting and Static Type Checking with Mypy\",\"datePublished\":\"2023-08-12T22:54:44+00:00\",\"dateModified\":\"2023-08-23T16:20:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/type-hinting-static-type-checking-mypy\\\/\"},\"wordCount\":1479,\"commentCount\":0,\"articleSection\":[\"Programming Languages\",\"Python\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/type-hinting-static-type-checking-mypy\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/type-hinting-static-type-checking-mypy\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/type-hinting-static-type-checking-mypy\\\/\",\"name\":\"Type Hinting and Static Type Checking with Mypy\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2023-08-12T22:54:44+00:00\",\"dateModified\":\"2023-08-23T16:20:23+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"description\":\"Mypy is a powerful static type checker for Python, allowing developers to enforce type constraints at compile time rather than at runtime.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/type-hinting-static-type-checking-mypy\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/type-hinting-static-type-checking-mypy\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/type-hinting-static-type-checking-mypy\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Type Hinting and Static Type Checking with Mypy\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Type Hinting and Static Type Checking with Mypy","description":"Mypy is a powerful static type checker for Python, allowing developers to enforce type constraints at compile time rather than at runtime.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/","og_locale":"en_US","og_type":"article","og_title":"Type Hinting and Static Type Checking with Mypy","og_description":"Mypy is a powerful static type checker for Python, allowing developers to enforce type constraints at compile time rather than at runtime.","og_url":"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/","article_published_time":"2023-08-12T22:54:44+00:00","article_modified_time":"2023-08-23T16:20:23+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"Type Hinting and Static Type Checking with Mypy","datePublished":"2023-08-12T22:54:44+00:00","dateModified":"2023-08-23T16:20:23+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/"},"wordCount":1479,"commentCount":0,"articleSection":["Programming Languages","Python"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/","url":"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/","name":"Type Hinting and Static Type Checking with Mypy","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2023-08-12T22:54:44+00:00","dateModified":"2023-08-23T16:20:23+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"description":"Mypy is a powerful static type checker for Python, allowing developers to enforce type constraints at compile time rather than at runtime.","breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/type-hinting-static-type-checking-mypy\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"Type Hinting and Static Type Checking with Mypy"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1780141266","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/862","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=862"}],"version-history":[{"count":8,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/862\/revisions"}],"predecessor-version":[{"id":902,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/862\/revisions\/902"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}