Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ae8f089
Commit pyproject.toml
hayat01sh1da Apr 11, 2026
290b1c1
Introduce type checking to existing Python files
hayat01sh1da Apr 11, 2026
f82b414
Introduce type checking to existing Python files
hayat01sh1da Apr 11, 2026
acea098
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da Apr 14, 2026
c810f56
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da Apr 21, 2026
54d2033
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da Apr 22, 2026
6d4ffae
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da Apr 22, 2026
728a684
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da Apr 22, 2026
0439f24
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da Apr 22, 2026
a059287
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da Apr 22, 2026
a47bdf2
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da Apr 23, 2026
f07d895
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da Apr 26, 2026
56f67bd
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da Apr 28, 2026
7e5af4f
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da Apr 30, 2026
b2d1ea6
Fix mypy command on GitHub Actions workflow
hayat01sh1da May 1, 2026
277885f
Add .mypy_cache to .gitignore
hayat01sh1da May 1, 2026
0768afe
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da May 2, 2026
a5b3b31
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da May 2, 2026
aa34c18
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da May 4, 2026
df00d8d
Merge branch 'master' into hayat01sh1da/python/introduce-mypy-typeche…
hayat01sh1da May 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,16 @@ jobs:
- name: pytest
working-directory: ./python
run: bash run_unittests.sh
# mypy:
# timeout-minutes: 10
# runs-on: ubuntu-latest
# needs: change-detection
# if: needs.change-detection.outputs.python-changes == 'true'
# steps:
# - uses: actions/checkout@v6
# - uses: ./.github/actions/setup-python
# - name: mypy
# working-directory: ./python
# run: mypy .
mypy:
timeout-minutes: 10
runs-on: ubuntu-latest
needs: change-detection
if: needs.change-detection.outputs.python-changes == 'true'
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python
- name: mypy
working-directory: ./python
env:
MYPYPATH: src
run: mypy --namespace-packages --explicit-package-bases .
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Python
python/**/__pycache__/
python/**/.mypy_cache

# JavaScript
javascript/node_modules/
6 changes: 4 additions & 2 deletions python/calculator_cli_app/src/application.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import sys
sys.path.append('./calculator_cli_app/src')
sys.path.append('./calculator_cli_app/src/lib')
Expand All @@ -8,7 +10,7 @@
from args_validation import __validate__

class Application:
def __init__(self, args):
def __init__(self, args: list[str]) -> None:
self.args_size = len(args)
if self.args_size > 0:
self.seed = args[0]
Expand All @@ -18,7 +20,7 @@ def __init__(self, args):
self.n = ''
self.calculation_query = CalculationQuery(self.seed)

def run(self):
def run(self) -> None:
__validate__(self.args_size, self.seed, __to_int_with_rescue__(self.n))

result = self.calculation_query.f(__to_int_with_rescue__(self.n))
Expand Down
5 changes: 4 additions & 1 deletion python/calculator_cli_app/src/lib/data_type_conversion.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
def __to_int_with_rescue__(n):
from __future__ import annotations


def __to_int_with_rescue__(n: str) -> int | str:
try:
return int(n)
except ValueError:
Expand Down
6 changes: 3 additions & 3 deletions python/calculator_cli_app/src/queries/calculation_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import json

class CalculationQuery:
def __init__(self, seed):
def __init__(self, seed: str) -> None:
self.seed = seed
self.uri = os.environ['CALCULATION_API']

def f(self, n):
def f(self, n: int) -> int:
if n == 0:
return 1
elif n == 2:
Expand All @@ -19,7 +19,7 @@ def f(self, n):

# private

def __ask_server__(self, n):
def __ask_server__(self, n: int) -> int:
params = { 'seed': self.seed, 'n': n }
req = urllib.request.Request('{}?{}'.format(self.uri, urllib.parse.urlencode(params)))
res = urllib.request.urlopen(req)
Expand Down
5 changes: 4 additions & 1 deletion python/calculator_cli_app/src/validations/args_validation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
def __validate__(args_size, seed, n):
from __future__ import annotations


def __validate__(args_size: int, seed: str, n: int | str) -> None:
if args_size > 2:
print('Too many arguments')
exit(1)
Expand Down
10 changes: 5 additions & 5 deletions python/calculator_cli_app/test/queries/test_calculation_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,28 @@
from calculation_query import CalculationQuery

class TestCalculationQuery(unittest.TestCase):
def setUp(self):
def setUp(self) -> None:
self.calculation_query = CalculationQuery('foo')
self.org_stdout = sys.stdout
sys.stdout = StringIO()
self.pycaches = glob.glob(os.path.join('.', '**', '__pycache__'), recursive = True)

def tearDown(self):
def tearDown(self) -> None:
sys.stdout = self.org_stdout
for pycache in self.pycaches:
if os.path.exists(pycache):
shutil.rmtree(pycache)

class TestArgumentZero(TestCalculationQuery):
def test_f_with_zero(self):
def test_f_with_zero(self) -> None:
self.assertEqual(self.calculation_query.f(0), 1)

class TestArgumentTwo(TestCalculationQuery):
def test_f_with_two(self):
def test_f_with_two(self) -> None:
self.assertEqual(self.calculation_query.f(2), 2)

class TestArgumentFour(TestCalculationQuery):
def test_f_with_four(self):
def test_f_with_four(self) -> None:
self.assertEqual(self.calculation_query.f(4), 348)

if __name__ == '__main__':
Expand Down
6 changes: 3 additions & 3 deletions python/calculator_cli_app/test/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@
from application import Application

class TestApplication(unittest.TestCase):
def setUp(self):
def setUp(self) -> None:
self.org_stdout = sys.stdout
sys.stdout = StringIO()
argv = ['foo', 4]
self.app = Application(args = argv)
self.pycaches = glob.glob(os.path.join('.', '**', '__pycache__'), recursive = True)

def test_run_success(self):
def test_run_success(self) -> None:
self.app.run()
self.assertEqual(sys.stdout.getvalue(), '348\n')

def tearDown(self):
def tearDown(self) -> None:
sys.stdout = self.org_stdout
for pycache in self.pycaches:
if os.path.exists(pycache):
Expand Down
5 changes: 4 additions & 1 deletion python/fibonacci_sequence/src/fibonacci.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
def fibonacci(init_num, iter):
from __future__ import annotations


def fibonacci(init_num: int, iter: int) -> list[int]:
current_num = init_num
next_num = current_num + 1
result = list()
Expand Down
8 changes: 4 additions & 4 deletions python/fibonacci_sequence/test/test_fibonacci.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@
from fibonacci import *

class TestFibonacci(unittest.TestCase):
def setUp(self):
def setUp(self) -> None:
self.pycaches = glob.glob(os.path.join('.', '**', '__pycache__'), recursive = True)

def tearDown(self):
def tearDown(self) -> None:
for pycache in self.pycaches:
if os.path.exists(pycache):
shutil.rmtree(pycache)

class TestCase1(TestFibonacci):
def test_fibonacci(self):
def test_fibonacci(self) -> None:
self.assertEqual(
fibonacci(0, 10),
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
)

class TestCase2(TestFibonacci):
def test_fibonacci(self):
def test_fibonacci(self) -> None:
self.assertEqual(
fibonacci(10, 10),
[10, 11, 21, 32, 53, 85, 138, 223, 361, 584]
Expand Down
4 changes: 2 additions & 2 deletions python/fizzbuzz/src/fizzbuzz.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def fizzbuzz_in_if(num):
def fizzbuzz_in_if(num: int) -> str:
if num % 3 == 0 and num % 5 == 0:
result = 'FizzBuzz'
elif num % 3 == 0:
Expand All @@ -9,6 +9,6 @@ def fizzbuzz_in_if(num):
result = str(num)
return result

def fizzbuzz_in_ternary(num):
def fizzbuzz_in_ternary(num: int) -> str:
result = 'FizzBuzz' if num % 3 == 0 and num % 5 == 0 else 'Fizz' if num % 3 == 0 else 'Buzz' if num % 5 == 0 else str(num)
return result
8 changes: 4 additions & 4 deletions python/fizzbuzz/test/test_fizzbuzz.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
from fizzbuzz import *

class TestFizzBuzz(unittest.TestCase):
def setUp(self):
def setUp(self) -> None:
self.pycaches = glob.glob(os.path.join('.', '**', '__pycache__'), recursive = True)

def tearDown(self):
def tearDown(self) -> None:
for pycache in self.pycaches:
if os.path.exists(pycache):
shutil.rmtree(pycache)

class TestIfStatement(TestFizzBuzz):
def test_fizzbuzz(self):
def test_fizzbuzz(self) -> None:
for num in range(1, 101):
if num % 3 == 0 and num % 5 == 0:
self.assertEqual(fizzbuzz_in_if(num), 'FizzBuzz')
Expand All @@ -28,7 +28,7 @@ def test_fizzbuzz(self):
self.assertEqual(fizzbuzz_in_if(num), str(num))

class TestTernaryStatement(TestFizzBuzz):
def test_fizzbuzz(self):
def test_fizzbuzz(self) -> None:
for num in range(1, 101):
if num % 3 == 0 and num % 5 == 0:
self.assertEqual(fizzbuzz_in_ternary(num), 'FizzBuzz')
Expand Down
6 changes: 3 additions & 3 deletions python/letter_inspection/src/application.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
class Application:
def __init__(self, str_1, str_2):
def __init__(self, str_1: str, str_2: str) -> None:
self.str_1 = str_1
self.str_2 = str_2

def exactly_equal_size_and_included(self):
def exactly_equal_size_and_included(self) -> bool:
return self.__sort_string__(self.str_1) == self.__sort_string__(self.str_2)

# private

def __sort_string__(self, str):
def __sort_string__(self, str: str) -> str:
return ''.join(sorted(str))
10 changes: 5 additions & 5 deletions python/letter_inspection/test/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from application import Application

class TestApplication(unittest.TestCase):
def setUp(self):
def setUp(self) -> None:
str_1 = 'hogefoobar'
str_2 = 'abefghooor'
str_3 = 'hoge'
Expand All @@ -17,24 +17,24 @@ def setUp(self):
self.pattern_3 = Application(str_1 = str_1, str_2 = str_4)
self.pycaches = glob.glob(os.path.join('.', '**', '__pycache__'), recursive = True)

def tearDown(self):
def tearDown(self) -> None:
for pycache in self.pycaches:
if os.path.exists(pycache):
shutil.rmtree(pycache)

class TestRegularCase(TestApplication):
def test_exactly_equal_size_and_included_1(self):
def test_exactly_equal_size_and_included_1(self) -> None:
self.assertTrue(self.pattern_1.exactly_equal_size_and_included())

class TestIrregularCase(TestApplication):
pass

class TestCase1(TestIrregularCase):
def test_exactly_equal_size_and_included_2(self):
def test_exactly_equal_size_and_included_2(self) -> None:
self.assertFalse(self.pattern_2.exactly_equal_size_and_included())

class TestCase1(TestIrregularCase):
def test_exactly_equal_size_and_included_3(self):
def test_exactly_equal_size_and_included_3(self) -> None:
self.assertFalse(self.pattern_3.exactly_equal_size_and_included())

if __name__ == '__main__':
Expand Down
4 changes: 2 additions & 2 deletions python/nabeatsu/src/nabeatsu.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
def go_crazy_in_if(num):
def go_crazy_in_if(num: int) -> str:
if num % 3 == 0 or '3' in str(num):
# Express the status of 'crazy' with '!'
result = str(num) + '!'
else:
result = str(num)
return result

def go_crazy_in_ternary(num):
def go_crazy_in_ternary(num: int) -> str:
# Express the status of 'crazy' with '!'
result = str(num) + '!' if num % 3 == 0 or '3' in str(num) else str(num)
return result
8 changes: 4 additions & 4 deletions python/nabeatsu/test/test_nabeatsu.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@
from nabeatsu import *

class TestNabeatsu(unittest.TestCase):
def setUp(self):
def setUp(self) -> None:
self.pycaches = glob.glob(os.path.join('.', '**', '__pycache__'), recursive = True)

def tearDown(self):
def tearDown(self) -> None:
for pycache in self.pycaches:
if os.path.exists(pycache):
shutil.rmtree(pycache)

class TestIfStatement(TestNabeatsu):
def test_go_crazy(self):
def test_go_crazy(self) -> None:
for num in range(1, 41):
if num % 3 == 0 or '3' in str(num):
self.assertEqual(go_crazy_in_if(num), str(num) + '!')
else:
self.assertEqual(go_crazy_in_if(num), str(num))

class TestTernaryStatement(TestNabeatsu):
def test_go_crazy(self):
def test_go_crazy(self) -> None:
for num in range(1, 41):
if num % 3 == 0 or '3' in str(num):
self.assertEqual(go_crazy_in_ternary(num), str(num) + '!')
Expand Down
5 changes: 5 additions & 0 deletions python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[tool.mypy]
python_version = "3.14"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
Loading