Thuta Learning

Python Project တစ်ခုကို မှန်ကန်စွာ စတင်တည်ဆောက်နည်း

Virtual environment ဖန်တီးခြင်းမှ dependency စီမံခြင်း၊ src layout ဖွဲ့စည်းခြင်း၊ ruff ဖြင့် lint စစ်ခြင်းနှင့် pytest ဖြင့် test ရေးခြင်းအထိ — နောက်ပိုင်းမှာ ပြန်ရှင်းရမယ့် ပြဿနာတွေ မဖြစ်အောင် Python project တစ်ခုကို အစကတည်းက မှန်မှန်ကန်ကန် စတင်တည်ဆောက်ပါမယ်။

Python Project တစ်ခုကို မှန်ကန်စွာ စတင်တည်ဆောက်နည်း cover illustration

Problem

Python စလေ့လာသူအများစုက script တစ်ဖိုင်တည်းကနေ စတင်ပြီး၊ package တွေကို global အဖြစ် pip install လုပ်၊ test မရေးဘဲ ဆက်သွားလေ့ရှိပါတယ်။ Project နှစ်ခုက version မတူတဲ့ library တစ်ခုတည်းကို လိုအပ်လာချိန်၊ ဒါမှမဟုတ် တခြားစက်တစ်လုံးမှာ project ကို run ဖို့ကြိုးစားချိန်မှာ ဒီအလေ့အထက ပြဿနာဖြစ်လာပါတယ် — 'ကျွန်တော့်စက်မှာတော့ အလုပ်လုပ်တယ်' ဆိုတဲ့ classic ပြဿနာပါပဲ။ ဒီ guide မှာ virtual environment, dependency file, src layout, linting နဲ့ testing တို့ကို အစကတည်းက စနစ်တကျ တည်ဆောက်ပြီး၊ နောက်ပိုင်းမှာ ပြန်ရှင်းရမယ့် အလုပ်တွေ မဖြစ်အောင် လုပ်ပါမယ်။

Requirements

  • Python 3.9 (သို့) အထက် — terminal မှာ python --version ဖြင့် စစ်ဆေးနိုင်သည်
  • Terminal တစ်ခု (Linux/macOS မှာ bash/zsh၊ Windows မှာ PowerShell သို့မဟုတ် Git Bash)
  • Code editor တစ်ခု (VS Code အကြံပြု)
  • Package install လုပ်ရန် internet connection

Project folder နှင့် Virtual Environment ဖန်တီးပါ

Virtual environment ဆိုတာ project တစ်ခုအတွက်သီးသန့် Python နှင့် package များကို သိမ်းထားပေးတဲ့ folder တစ်ခုပါ။ ဒါမရှိဘဲ pip install လုပ်လိုက်ရင် package တွေဟာ system တစ်ခုလုံးအတွက် global နေရာမှာ ရောက်သွားပြီး၊ project A က Django 4 လိုချင်၊ project B က Django 5 လိုချင်တဲ့အခါ တစ်ခုနဲ့တစ်ခု ပဋိပက္ခဖြစ်ပါတယ်။ venv က ဒီပြဿနာကို project တစ်ခုချင်းစီအတွက် သီးခြားခွဲထားပေးခြင်းဖြင့် ဖြေရှင်းပါတယ်။

Terminal
$ mkdir greeter && cd greeter
Terminal
$ python -m venv .venv

ဖန်တီးပြီးရင် activate လုပ်ရပါမယ် — activate မလုပ်ဘဲ pip install လုပ်မိရင် global ထဲ ပြန်ရောက်သွားပါလိမ့်မယ်။ Activate command က operating system အလိုက် မတူပါဘူး: Linux/macOS မှာ source .venv/bin/activate၊ Windows PowerShell မှာ .venv\Scripts\Activate.ps1၊ Git Bash မှာ source .venv/Scripts/activate ဖြစ်ပါတယ်။ အောင်မြင်ရင် terminal prompt ရှေ့မှာ (.venv) ဆိုတဲ့ စာသားလေး ပေါ်လာပါလိမ့်မယ် — ဒါက အခု venv ထဲမှာ ရောက်နေပြီဆိုတဲ့ အမှတ်အသားပါ။

Terminal
$ source .venv/bin/activate

.venv ကို git ထဲ မတင်ပါနှင့်

.venv folder ထဲမှာ megabyte ရာနဲ့ချီတဲ့ binary တွေပါဝင်ပြီး၊ သင့်စက်ရဲ့ path တွေကို hardcode လုပ်ထားလို့ တခြားစက်မှာ အလုပ်မလုပ်ပါဘူး။ နောက်ဆုံးအဆင့်မှာ .gitignore ထဲ ထည့်ပါမယ် — အဲဒါက dependency စာရင်း (pyproject.toml) ကိုသာ git ထဲထားပြီး၊ တခြားသူတွေက ကိုယ်ပိုင် venv ကို ပြန်ဆောက်ယူတဲ့ ပုံစံပါ။

src Layout ဖြင့် Project ဖွဲ့စည်းပုံ ဆောက်ပါ

Code ကို project root မှာ တိုက်ရိုက်မထားဘဲ src/ folder အောက်မှာ ထားတဲ့ ပုံစံကို 'src layout' လို့ခေါ်ပါတယ်။ အကျိုးကျေးဇူးက ရှင်းပါတယ် — test တွေ run တဲ့အခါ Python က သင့် package ကို install လုပ်ထားသလိုမျိုး ရှာရမှာဖြစ်လို့၊ 'ကျွန်တော့်စက်မှာတော့ import ရတယ်' ဆိုတဲ့ မှားယွင်းသော အောင်မြင်မှုမျိုး မဖြစ်တော့ပါဘူး။ Test က တကယ့် package structure ကို စမ်းသပ်ပေးမှာ ဖြစ်ပါတယ်။

Terminal
$ mkdir -p src/greeter tests
Terminal
$ touch src/greeter/__init__.py src/greeter/core.py tests/test_core.py

__init__.py ဖိုင်က folder တစ်ခုကို Python package အဖြစ် သတ်မှတ်ပေးတဲ့ အမှတ်အသားပါ (ဗလာဖြစ်နေလည်း ရပါတယ်)။ ပြီးရင် src/greeter/core.py ထဲမှာ လက်တွေ့ code အနည်းငယ် ရေးထည့်ပါ။

python
def greet(name: str) -> str:
    """Return a friendly greeting for name."""
    if not name:
        raise ValueError("name must not be empty")
    return f"Hello, {name}!"

pyproject.toml ဖြင့် Dependency နှင့် Tool များ သတ်မှတ်ပါ

pyproject.toml က ခေတ်မီ Python project တွေရဲ့ တစ်ခုတည်းသော configuration file ဖြစ်ပါတယ် — dependency စာရင်း၊ pytest setting၊ ruff setting အားလုံးကို ဒီတစ်ဖိုင်ထဲမှာပဲ ထားနိုင်ပါတယ် (ယခင်က requirements.txt, setup.py, pytest.ini, .flake8 စသဖြင့် ဖိုင်များစွာ ခွဲထားရပါတယ်)။ Project root မှာ အောက်ပါအတိုင်း ဖန်တီးပါ။

toml
[project]
name = "greeter"
version = "0.1.0"
requires-python = ">=3.9"
dependencies = []

[project.optional-dependencies]
dev = ["pytest", "ruff"]

[tool.pytest.ini_options]
pythonpath = ["src"]
testpaths = ["tests"]

[tool.ruff]
line-length = 88

pythonpath = ["src"] က အရေးအကြီးဆုံး လိုင်းပါ

src layout သုံးတဲ့အခါ pytest က src/ ထဲက package ကို default အနေနဲ့ ရှာမတွေ့ပါဘူး။ ဒီလိုင်းက pytest ကို src/ folder ထဲ ဝင်ရှာဖို့ ပြောပေးတာပါ — မထည့်ရင် test run လိုက်တာနဲ့ ModuleNotFoundError: No module named 'greeter' ဆိုပြီး ချက်ချင်း fail ဖြစ်ပါလိမ့်မယ်။ src layout သုံးသူတွေ အများဆုံး ကြုံရတဲ့ ပြဿနာက ဒါပါပဲ။

Terminal
$ python -m pip install pytest ruff

Test ရေးပြီး pytest ဖြင့် Run ပါ

Test ဆိုတာ code မှန်ကန်စွာ အလုပ်လုပ်မလုပ် အလိုအလျောက် စစ်ပေးတဲ့ code ပါ။ အောင်မြင်တဲ့ လမ်းကြောင်း (happy path) တစ်ခုနဲ့ error ဖြစ်သင့်တဲ့ လမ်းကြောင်း တစ်ခု — အနည်းဆုံး နှစ်ခု ရေးတာက စတင်ရန် ကောင်းမွန်တဲ့ အလေ့အထပါ။ tests/test_core.py ထဲမှာ ရေးပါ။

python
import pytest

from greeter.core import greet


def test_greet_returns_greeting():
    assert greet("Aung") == "Hello, Aung!"


def test_greet_rejects_empty_name():
    with pytest.raises(ValueError):
        greet("")
Terminal
$ python -m pytest
You should see
============================= test session starts =============================
platform win32 -- Python 3.9.7, pytest-8.4.2, pluggy-1.6.0
rootdir: /path/to/greeter
configfile: pyproject.toml
testpaths: tests
collected 2 items

tests/test_core.py ..                                                    [100%]

============================== 2 passed in 0.04s ==============================

ruff ဖြင့် Code ကို Lint နှင့် Format လုပ်ပါ

ruff က Python အတွက် linter (အမှားနှင့် စာရေးဟန် ပြဿနာများ ရှာဖွေပေးသည်) နှင့် formatter (code ကို ပုံစံတကျ ပြန်စီပေးသည်) နှစ်မျိုးလုံး လုပ်ပေးနိုင်တဲ့ tool တစ်ခုပါ။ ယခင်က flake8, isort, black စတဲ့ tool သုံးမျိုးလောက် ခွဲသုံးရတာကို ruff တစ်ခုတည်းက အစားထိုးပေးနိုင်ပြီး၊ Rust နဲ့ ရေးထားလို့ အလွန်မြန်ပါတယ်။

Terminal
$ python -m ruff check .
You should see
All checks passed!

Format ပြန်စီချင်ရင် ruff format ကို သုံးပါ။ ဒါက code ရဲ့ အလုပ်လုပ်ပုံကို မပြောင်းဘဲ spacing, quote, line break တွေကိုသာ ပုံစံတကျ ပြင်ပေးတာဖြစ်လို့ commit မလုပ်ခင် တစ်ကြိမ် run လိုက်တာက အလေ့အထကောင်းတစ်ခုပါ။

Terminal
$ python -m ruff format .

.gitignore ထည့်ပြီး Git ဖြင့် စတင်ပါ

နောက်ဆုံးအဆင့်ကတော့ git ထဲ မတင်သင့်တဲ့ ဖိုင်တွေကို .gitignore ဖြင့် ဖယ်ထုတ်ခြင်းပါ — .venv (အရွယ်ကြီးပြီး စက်တစ်လုံးချင်းစီအတွက် သီးသန့်)၊ __pycache__ (Python က အလိုအလျောက် ထုတ်ပေးသော cache)၊ .pytest_cache နှင့် .ruff_cache တို့ ဖြစ်ပါတယ်။

text
.venv/
__pycache__/
*.py[cod]
.pytest_cache/
.ruff_cache/
.env
Terminal
$ git init && git add . && git commit -m "Initial project setup"

တခြားစက်တစ်လုံးမှာ ပြန်စဖို့

ဒီပုံစံနဲ့ တည်ဆောက်ထားရင် တခြားစက်မှာ project ကို clone လုပ်ပြီး python -m venv .venv၊ activate၊ python -m pip install -e ".[dev]" သုံးကြောင်းတည်းနဲ့ တစ်ထပ်တည်း အလုပ်လုပ်တဲ့ environment ပြန်ရပါပြီ — 'ကျွန်တော့်စက်မှာတော့ အလုပ်လုပ်တယ်' ပြဿနာ မဖြစ်တော့ပါဘူး။

Expected result

Project folder ထဲမှာ .venv/ (git ထဲမပါ)၊ src/greeter/ package၊ tests/ folder၊ pyproject.toml နှင့် .gitignore တို့ ရှိနေပါမည်။ python -m pytest ကို run လိုက်ရင် '2 passed' ဆိုပြီး test နှစ်ခုလုံး အောင်မြင်ပြီး၊ python -m ruff check . က 'All checks passed!' လို့ ပြပါမည်။ Project ကို git repository တစ်ခုအဖြစ် commit လုပ်ပြီး တခြားစက်တစ်လုံးမှာ clone လုပ်၍ ပြန်လည်တည်ဆောက်နိုင်ပါပြီ။

Troubleshooting

  • pytest run လိုက်ရင် 'ModuleNotFoundError: No module named greeter' တက်နေလျှင် — pyproject.toml ထဲက [tool.pytest.ini_options] အောက်မှာ pythonpath = ["src"] ပါမပါ စစ်ပါ။ src layout သုံးရင် ဒီလိုင်းမပါဘဲ pytest က package ကို ရှာမတွေ့ပါ။
  • pip install လုပ်ပြီးပေမယ့် import မရလျှင် — venv ကို activate မလုပ်ရသေးတာ ဖြစ်နိုင်ပါတယ်။ Terminal prompt ရှေ့မှာ (.venv) ပေါ်မပေါ် ကြည့်ပါ၊ ဒါမှမဟုတ် which python (Windows PowerShell မှာ Get-Command python) ဖြင့် venv ထဲက python ကို ညွှန်နေမနေ စစ်ပါ။
  • Windows PowerShell မှာ activate script က 'running scripts is disabled' ဆိုပြီး ငြင်းလျှင် — Set-ExecutionPolicy -Scope CurrentUser RemoteSigned ဖြင့် policy ကို ပြောင်းပါ (သို့) Git Bash ကို အသုံးပြုပါ။
  • ruff က မမျှော်လင့်ထားသော error အများအပြား ပြနေလျှင် — pyproject.toml ထဲက line-length setting ကို team ရဲ့ စံနှင့် ကိုက်အောင် ချိန်ပါ၊ ပြီးရင် ruff format . ကို အရင် run ပြီးမှ ruff check . ကို ပြန်run ပါ။

Related tutorials