{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Manual Validation Testing\n", "\n", "Here are the basic validation tests you can perform in a terminal or here from a Jupyter notebook. \n", "Basic `mypy`, `flake8`, and `pytest` commands and results. These test can also be fond in `tox.ini` were they are run against Python 3.9 and 3.10.\n", "\n", "---\n", "\n", "## `pytest` \n", "\n", "__~45.6 seconds to run__\n", "\n", "Run all the `/tests` to make sure the code is behaving as expected.\n", "\n", ">Note: Remember to add tests if new behavior is added" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m============================= test session starts ==============================\u001b[0m\n", "platform linux -- Python 3.10.2, pytest-7.1.1, pluggy-1.0.0\n", "rootdir: /workspaces/yamllint\n", "plugins: anyio-3.5.0, env-0.6.2\n", "collected 356 items \u001b[0m\u001b[1m\u001b[1m\u001b[1m\u001b[1m\u001b[1m\u001b[1m\n", "\n", "tests/test_cli.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 7%]\u001b[0m\n", "tests/test_config.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 12%]\u001b[0m\n", "tests/test_linter.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 14%]\u001b[0m\n", "tests/test_module.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 16%]\u001b[0m\n", "tests/test_parser.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 16%]\u001b[0m\n", "tests/test_spec_examples.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 29%]\n", "\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 42%]\u001b[0m\n", "tests/test_syntax_errors.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 44%]\u001b[0m\n", "tests/test_yamllint_directives.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 47%]\u001b[0m\n", "tests/rules/test_braces.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 50%]\u001b[0m\n", "tests/rules/test_brackets.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 52%]\u001b[0m\n", "tests/rules/test_colons.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 55%]\u001b[0m\n", "tests/rules/test_commas.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 57%]\u001b[0m\n", "tests/rules/test_comments.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 61%]\u001b[0m\n", "tests/rules/test_comments_indentation.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 62%]\u001b[0m\n", "tests/rules/test_common.py \u001b[32m.\u001b[0m\u001b[32m [ 63%]\u001b[0m\n", "tests/rules/test_document_end.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 64%]\u001b[0m\n", "tests/rules/test_document_start.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 65%]\u001b[0m\n", "tests/rules/test_empty_lines.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 67%]\u001b[0m\n", "tests/rules/test_empty_values.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 72%]\u001b[0m\n", "tests/rules/test_hyphens.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 73%]\u001b[0m\n", "tests/rules/test_indentation.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 84%]\n", "\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 85%]\u001b[0m\n", "tests/rules/test_key_duplicates.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 86%]\u001b[0m\n", "tests/rules/test_key_ordering.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 89%]\u001b[0m\n", "tests/rules/test_line_length.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 91%]\u001b[0m\n", "tests/rules/test_new_line_at_end_of_file.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 92%]\u001b[0m\n", "tests/rules/test_new_lines.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 93%]\u001b[0m\n", "tests/rules/test_octal_values.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 94%]\u001b[0m\n", "tests/rules/test_quoted_strings.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 97%]\u001b[0m\n", "tests/rules/test_trailing_spaces.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [ 98%]\u001b[0m\n", "tests/rules/test_truthy.py \u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m.\u001b[0m\u001b[32m [100%]\u001b[0m\n", "\n", "\u001b[32m============================= \u001b[32m\u001b[1m356 passed\u001b[0m\u001b[32m in 44.09s\u001b[0m\u001b[32m =============================\u001b[0m\n" ] } ], "source": [ "!cd .. && pytest tests" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## `flake8` \n", "\n", "__~ 2.9 seconds to run__\n", "\n", "Run `flake8` on both the `/src` and `/tests` to identify:\n", "\n", "- coding style (PEP8)\n", "- programming errors (like “library imported but unused” and “Undefined name”)\n", "- cyclomatic complexity\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "!flake8 ../yamllint" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "!flake8 ../tests" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## `mypy` \n", "\n", "__~ 2.9 seconds to run__\n", "\n", "Run `mypy` on both the `/src` to identify\"\n", "\n", "- missing static type passing between methods" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "../yamllint/parser.py:17: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/linter.py:19: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/truthy.py:125: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/quoted_strings.py:120: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/octal_values.py:76: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/line_length.py:101: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/key_ordering.py:86: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/key_duplicates.py:57: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/empty_values.py:78: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/document_start.py:75: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/document_end.py:85: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/common.py:19: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/indentation.py:203: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/hyphens.py:79: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/comments_indentation.py:78: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/commas.py:105: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/colons.py:82: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/brackets.py:137: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/braces.py:136: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "../yamllint/rules/braces.py:136: \u001b[34mnote:\u001b[m Hint: \u001b[m\u001b[1m\"python3 -m pip install types-PyYAML\"\u001b[m\u001b[m\n", "../yamllint/rules/braces.py:136: \u001b[34mnote:\u001b[m (or run \u001b[m\u001b[1m\"mypy --install-types\"\u001b[m to install all missing stub packages)\u001b[m\n", "../yamllint/rules/braces.py:136: \u001b[34mnote:\u001b[m See \u001b[4mhttps://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports\u001b[m\u001b[m\n", "../yamllint/config.py:19: \u001b[1m\u001b[31merror:\u001b[m Skipping analyzing \u001b[m\u001b[1m\"pathspec\"\u001b[m: module is installed, but missing library stubs or py.typed marker\u001b[m\n", "../yamllint/config.py:20: \u001b[1m\u001b[31merror:\u001b[m Library stubs not installed for \u001b[m\u001b[1m\"yaml\"\u001b[m (or incompatible with Python 3.10)\u001b[m\n", "\u001b[1m\u001b[31mFound 21 errors in 20 files (checked 29 source files)\u001b[m\n" ] } ], "source": [ "!mypy ../yamllint" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## `tox` \n", "\n", "__~ 12 minutes and 35 seconds to run__ the first time because each virtual environment has to be\n", "created. On the second run the time is __~ 3 minutes and 47 seconds to run__ \n", "\n", "Run `tox` to do all of the above again for multiple Python versions. The results are piped into a markdown file that you can inspect and update with your notes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# this project doesn't have a tox (yet)\n", "#!cd .. && sudo tox > tox_run.md" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] } ], "metadata": { "interpreter": { "hash": "949777d72b0d2535278d3dc13498b2535136f6dfe0678499012e853ee9abcab1" }, "kernelspec": { "display_name": "Python 3.10.2 64-bit", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.2" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }