Sorun: "Benim makinemde çalışıyordu"
Anadolu Market'in raporlama betiği senin bilgisayarında kusursuz çalışıyor; iş arkadaşın çalıştırınca ModuleNotFoundError: No module named 'openpyxl' alıyor. Bir başka projede pandas'ın eski sürümü gerekiyor, ama bilgisayarına yenisini kurdun ve eski proje bozuldu. İki sorunun da kaynağı aynı: paketler (package) bilgisayara global kurulmuş. Çözüm iki parçalı: her projeye kendi izole paket klasörü (sanal ortam, virtual environment) ve projenin hangi paketlerin hangi sürümünü istediğini yazan bir liste (requirements.txt ya da pyproject.toml).
Sanal ortam: venv
venv, standart kütüphanenin parçasıdır. Proje klasöründe şu üç komut yeter:
python -m venv .venv— proje içinde.venvklasörü oluşturur; içinde ayrı bir Python ve boş bir paket klasörü vardır.- Etkinleştir: Windows'ta
.venv\Scripts\activate, macOS/Linux'tasource .venv/bin/activate. Terminal satırının başında(.venv)belirir. - Artık
pip installyalnızca bu klasöre kurar;deactivateile çıkarsın.
Kural: her proje kendi .venv'ine sahip olur ve bu klasör asla Git'e girmez (sonraki derste .gitignore'a yazacağız). Ortamı başkasıyla paylaşmazsın; paylaştığın şey bağımlılık listesidir, ortamı herkes kendi makinesinde o listeden yeniden kurar.
import sys
from pathlib import Path
# Sanal ortam etkin mi? sys.prefix sanal ortamın yolunu, base_prefix gerçek kurulumu gösterir
etkin = sys.prefix != sys.base_prefix
print("sanal ortam etkin mi?", etkin)
print("Python sürümü:", sys.version_info.major, ".", sys.version_info.minor, sep="")
# Tipik bir proje yerleşimi (gösterim)
agac = {
"anadolu-rapor/": ["pyproject.toml", "requirements.txt", "README.md", ".gitignore", ".venv/ (Git'e girmez)", "src/anadolu_rapor/", "tests/"],
}
for kok, parcalar in agac.items():
print(kok)
for p in parcalar:
print(" ", p)
pip: kur, listele, dondur
pip Python'ın paket yöneticisidir ve PyPI (Python Package Index) deposundan indirir. Günlük komutlar:
| Komut | Ne yapar |
|---|---|
| pip install pandas | En yeni uyumlu sürümü kurar |
| pip install "pandas==2.2.2" | Tam o sürümü kurar |
| pip install -r requirements.txt | Listedeki her şeyi kurar |
| pip install -e . | Projenin kendisini düzenlenebilir modda kurar (pyproject gerekir) |
| pip list | Kurulu paketleri gösterir |
| pip freeze > requirements.txt | Kurulu paketleri tam sürümle dosyaya yazar |
| pip uninstall pandas | Kaldırır |
| pip install --upgrade pip | pip'in kendisini günceller |
pip freeze çıktısı paket==sürüm satırlarından oluşur. Bu, "o gün çalışan tam kombinasyon"un fotoğrafıdır; dağıtımda (deployment) bu dosyayı kullanırsın ki sunucuda da birebir aynı sürümler kurulsun.
Sürüm belirteçleri ve semver
Paketler çoğunlukla anlamsal sürümleme (semantic versioning, semver) kullanır: MAJOR.MINOR.PATCH. PATCH hata düzeltmesidir, MINOR geriye uyumlu yeni özellik, MAJOR ise uyumu bozabilen değişiklik. requirements.txt satırında hangi sürümleri kabul ettiğini belirtirsin:
| Belirteç | Anlamı | Ne zaman |
|---|---|---|
| pandas==2.2.2 | Tam olarak 2.2.2 | Dağıtım, tekrarlanabilirlik |
| pandas>=2.0 | 2.0 ve üstü, sınırsız | Kütüphane yazarken (esnek) |
| pandas~=2.2.0 | >=2.2.0 ve <2.3 (son basamak serbest) | Yama güncellemelerine açık |
| pandas>=2.0,<3 | 2.x serisi | MAJOR kırılmasından korunmak |
| pandas | Herhangi bir sürüm | Hızlı deneme; üretimde kaçın |
Sürüm metnini karşılaştırırken metin karşılaştırması yanıltır: "2.10.0" < "2.9.0" metin olarak doğru ama sürüm olarak yanlıştır. Parçalara bölüp tam sayıya çevirmek gerekir; aşağıdaki küçük ayrıştırıcı requirements satırlarını sözlüğe döker ve sürümü doğru karşılaştırır.
import re
def surum_demeti(s: str) -> tuple[int, ...]:
return tuple(int(p) for p in s.split("."))
print('"2.10.0" < "2.9.0" metin olarak:', "2.10.0" < "2.9.0")
print("demet olarak:", surum_demeti("2.10.0") < surum_demeti("2.9.0"))
requirements = """
# Anadolu Market rapor aracı
pandas==2.2.2
openpyxl>=3.1
requests~=2.31.0
rich
"""
desen = re.compile(r"^([A-Za-z0-9_.-]+)\s*(==|>=|~=|<=|>|<)?\s*([0-9.]+)?$")
for satir in requirements.splitlines():
satir = satir.strip()
if not satir or satir.startswith("#"):
continue
ad, op, ver = desen.match(satir).groups()
print(f"{ad:10} {op or '(her sürüm)':12} {ver or ''}")
Düzenli ifade üç parça yakalar: paket adı, işleç, sürüm. Yorum ve boş satırlar atlanır. Gerçek requirements dosyalarında ek kurallar da bulunur (ortam işaretleri, -r ile başka dosya), ama günlük işte bu kadarı yeter.
~=2.2 ile ~=2.2.0 farklıdır. İlki ">=2.2, <3.0" (minor serbest), ikincisi ">=2.2.0, <2.3" (yalnızca patch serbest). Son basamak kaç haneli yazıldıysa o basamak serbest kalır.pyproject.toml: modern standart
Yeni projelerde bağımlılıklar requirements.txt yerine (ya da onunla birlikte) pyproject.toml içinde tutulur. TOML, okunur bir yapılandırma biçimidir; Python 3.11'den beri standart kütüphanedeki tomllib ile okunur (yalnızca okuma; yazmak için dış paket gerekir). Aynı dosya projenin adını, sürümünü ve araç ayarlarını da taşır.
import tomllib
pyproject = """
[project]
name = "anadolu-rapor"
version = "0.3.1"
requires-python = ">=3.11"
dependencies = [
"pandas==2.2.2",
"openpyxl>=3.1",
]
[project.optional-dependencies]
dev = ["pytest>=8", "ruff"]
[tool.ruff]
line-length = 100
"""
veri = tomllib.loads(pyproject)
proje = veri["project"]
print(proje["name"], proje["version"], "| Python:", proje["requires-python"])
print("bağımlılıklar:", proje["dependencies"])
print("geliştirme:", proje["optional-dependencies"]["dev"])
print("ruff satır uzunluğu:", veri["tool"]["ruff"]["line-length"])
optional-dependencies altındaki dev grubu yalnızca geliştiricilerin kurduğu paketlerdir (test, biçimlendirici); pip install -e ".[dev]" ile kurulur. Üretim sunucusuna pytest kurmazsın.
uv (Rust ile yazılmış, çok hızlı) ve poetry, sanal ortamı ve kilit dosyasını (lock file) otomatik yönetir: uv add pandas hem pyproject'e yazar hem kurar hem uv.lock üretir. Kilit dosyası, pip freeze'in modern karşılığıdır: her bağımlılığın bağımlılığının bile tam sürümünü tutar.Bağımlılık çatışması
Paket A, requests>=2.31 isterken paket B requests<2.30 isterse pip "ResolutionImpossible" hatası verir: iki koşulu aynı anda sağlayan sürüm yok. Çatışma (dependency conflict) genellikle eski bir paketin güncellenmemesinden doğar. Çözüm sırası: önce iki paketin daha yeni sürümlerini dene; olmuyorsa birini değiştir; son çare, çatışan işi ayrı sanal ortamda çalışan ayrı bir araca taşı. Çatışmayı erken fark etmek için bağımlılık listesini küçük tut: gerçekten kullandığın paketleri yaz, "bir gün lazım olur" diye ekleme.
def aralikta(ver: tuple, kosullar: list[tuple[str, tuple]]) -> bool:
for op, hedef in kosullar:
if op == ">=" and not ver >= hedef: return False
if op == "<" and not ver < hedef: return False
if op == "==" and not ver == hedef: return False
return True
# A: requests>=2.31 | B: requests<2.30
kosullar = [(">=", (2, 31, 0)), ("<", (2, 30, 0))]
adaylar = [(2, 28, 0), (2, 29, 0), (2, 31, 0), (2, 32, 3)]
uygun = [v for v in adaylar if aralikta(v, kosullar)]
print("iki koşulu da sağlayan sürüm:", uygun or "YOK -> çatışma")
Derinleş: Kurulumdan kilit dosyasına paket yönetimi
Bu bölüm bir başvuru kılavuzudur: her işletim sisteminde sanal ortamı kurup etkinleştirme, pip'in tüm günlük komutları, requirements ve constraints dosyaları, pip-tools, uv, poetry, conda ve pipx ile iş akışları ve en sık karşılaşılan hataların çözümü. Komutları kendi bilgisayarında, proje klasöründe dene; tarayıcıdaki örnekler ise ortamı ve sürümleri Python'dan nasıl sorgulayacağını gösterir. Altın kural: pip yerine python -m pip yaz; böylece paket, o an çalışan Python'a kurulur.
1. venv: her işletim sisteminde oluştur, etkinleştir, doğrula
| Sistem / kabuk | Oluştur | Etkinleştir |
|---|---|---|
| Windows – PowerShell | py -3.12 -m venv .venv | .venv\Scripts\Activate.ps1 |
| Windows – cmd | py -m venv .venv | .venv\Scripts\activate.bat |
| Windows – Git Bash | py -m venv .venv | source .venv/Scripts/activate |
| macOS / Linux – bash, zsh | python3 -m venv .venv | source .venv/bin/activate |
| Linux/macOS – fish | python3 -m venv .venv | source .venv/bin/activate.fish |
| csh / tcsh | python3 -m venv .venv | source .venv/bin/activate.csh |
Etkinleşince istemde (prompt) (.venv) görünür. Çıkmak için her kabukta deactivate. Etkinleştirmeden de çalışabilirsin: .venv/bin/python betik.py (Windows'ta .venv\Scripts\python.exe betik.py) doğrudan o ortamın Python'ını kullanır; zamanlanmış görevlerde ve CI'da en güvenli yol budur.
# Windows PowerShell: "running scripts is disabled on this system" hatası Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned .venv\Scripts\Activate.ps1 where.exe python # ilk satır ...\.venv\Scripts\python.exe olmalı # Debian/Ubuntu: "ensurepip is not available" hatası sudo apt install python3-venv # (ya da python3.12-venv) python3 -m venv .venv && source .venv/bin/activate which python # .../proje/.venv/bin/python olmalı # Ortamı sıfırdan kurmak (bozulduysa): klasörü sil, yeniden oluştur rm -rf .venv # Windows: Remove-Item -Recurse -Force .venv python3 -m venv .venv --upgrade-deps # pip'i de güncel kurar
Hangi ortamda olduğunu kodla da anlayabilirsin: sanal ortamda sys.prefix ortam klasörünü, sys.base_prefix ise ana kurulumu gösterir.
import sys, sysconfig, platform
from pathlib import Path
print("Python:", platform.python_version(), "| sistem:", platform.system())
print("Çalışan yorumlayıcı:", sys.executable)
print("Sanal ortamda mı?", sys.prefix != sys.base_prefix)
print("Paketler buraya kurulur:", sysconfig.get_paths()["purelib"])
isaret = Path(sysconfig.get_paths()["stdlib"]) / "EXTERNALLY-MANAGED"
print("PEP 668 korumalı sistem Python\'ı mı?", isaret.exists())
2. pip: günlük komutların tamamı
python -m pip install requests # en son sürüm python -m pip install "pandas>=2.2,<3" # aralık (tırnak şart: < ve > kabuk yönlendirmesidir) python -m pip install pandas==2.2.3 # tam sürüm python -m pip install -U pandas # güncelle (--upgrade) python -m pip install -U pip # pip'in kendisini güncelle python -m pip install -r requirements.txt # dosyadan python -m pip install -e . # projeyi düzenlenebilir (editable) kur python -m pip install "httpx[http2]" # ekstralarla (extras) python -m pip install --dry-run -r requirements.txt # ne kurulacağını göster, kurma python -m pip uninstall -y requests # kaldır (bağımlılıkları KALDIRMAZ) python -m pip show pandas # sürüm, konum, Requires, Required-by python -m pip list # kurulu paketler python -m pip list --outdated # güncellenebilenler python -m pip freeze > requirements.txt # tam sürümlerle döküm python -m pip check # kırık bağımlılık var mı? python -m pip download -d paketler -r requirements.txt # internetsiz kurulum için indir python -m pip install --no-index --find-links paketler -r requirements.txt python -m pip cache purge # bozuk önbelleği temizle python -m pip config list # aktif pip ayarları
pip uninstall pandas numpy'ı kaldırmaz. Ortam karıştıysa paket paket temizlemek yerine .venv'i silip requirements.txt'den yeniden kurmak daha hızlı ve güvenlidir.3. requirements ve constraints
requirements.txt "bunları kur" der. constraints.txt (-c) ise "kurarsan şu sürümü kullan" der ama kendisi hiçbir şey kurmaz. Şirket genelinde onaylı sürümleri tek dosyada tutmak için idealdir: her proje kendi requirements'ını yazar, sürümler ortak constraints'ten gelir.
# requirements.txt pandas>=2.2 requests -c constraints.txt # dosya içinden de bağlanabilir # constraints.txt (şirket onaylı sürümler) pandas==2.2.3 numpy==2.1.3 requests==2.32.3 django==5.1.4 # kimse istemezse kurulmaz python -m pip install -r requirements.txt -c constraints.txt
Kurulu sürümleri Python içinden okumak (ör. bir betiğin başında "doğru sürüm mü?" kontrolü) için importlib.metadata kullanılır:
from importlib.metadata import version, PackageNotFoundError
for paket in ("pip", "pandas", "olmayan-paket-xyz"):
try:
print(f"{paket:20} {version(paket)}")
except PackageNotFoundError:
print(f"{paket:20} KURULU DEĞİL -> python -m pip install {paket}")
4. pip-tools: elle yazılan liste + otomatik kilit
python -m pip install pip-tools # requirements.in : yalnız doğrudan ihtiyaçlar # pandas>=2.2 # httpx pip-compile requirements.in # -> requirements.txt (tüm alt bağımlılıklar sabit, yorumlu) pip-compile --upgrade-package httpx # yalnız birini güncelle pip-compile --generate-hashes # özet doğrulamalı kilit (güvenlik) pip-sync requirements.txt # ortamı dosyayla BİREBİR eşitle (fazlaları kaldırır)
5. uv: hızlı, hepsi bir arada
uv, Rust ile yazılmış, pip'ten kat kat hızlı bir araçtır; Python sürümü kurmayı, sanal ortamı, kilit dosyasını ve araç kurulumunu tek komutta toplar.
# Kurulum: macOS/Linux curl -LsSf https://astral.sh/uv/install.sh | sh # Windows PowerShell powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" uv python install 3.12 # Python'ı uv kursun uv venv # .venv oluşturur (--python 3.12 ile sürüm seç) uv pip install -r requirements.txt # pip ile aynı arayüz, çok daha hızlı uv pip compile requirements.in -o requirements.txt # pip-tools karşılığı uv pip sync requirements.txt # Proje modu (pyproject.toml + uv.lock) uv init anadolu-rapor && cd anadolu-rapor uv add pandas "httpx>=0.27" # pyproject'e yazar, kilitler, kurar uv add --dev pytest ruff # geliştirme bağımlılığı uv remove httpx uv lock # uv.lock'u güncelle (kurmadan) uv lock --upgrade-package pandas uv sync # ortamı kilide göre kur (CI'da: uv sync --locked) uv run python rapor.py # ortamı etkinleştirmeden çalıştır uv tool install ruff # pipx karşılığı
6. poetry
pipx install poetry poetry new ilgaz-bank # ya da mevcut projede: poetry init poetry add pandas@^2.2 # ^2.2 = >=2.2,<3.0 poetry add --group dev pytest poetry install # poetry.lock'tan kur poetry lock # kilidi yenile poetry run pytest poetry env info --path # ortamın yeri poetry export -f requirements.txt -o requirements.txt # (poetry-plugin-export gerekir)
7. conda (Anaconda / Miniconda / Miniforge)
Conda yalnız Python paketlerini değil, C/C++ kütüphaneleri ve hatta Python'ın kendisini yönetir; GDAL, CUDA gibi derlenmiş bağımlılıklarda ve veri bilimi ekiplerinde yaygındır. Kurumsal lisans koşulları nedeniyle birçok şirket varsayılan kanal yerine conda-forge ve Miniforge kullanır.
conda create -n anadolu python=3.12 pandas -c conda-forge
conda activate anadolu # çıkış: conda deactivate
conda install -c conda-forge scikit-learn
conda env export --from-history > environment.yml # yalnız senin istediklerin
conda env create -f environment.yml
conda env list
conda remove -n anadolu --all
# environment.yml
name: anadolu
channels: [conda-forge]
dependencies:
- python=3.12
- pandas>=2.2
- pip
- pip:
- rich==13.9.4 # conda'da olmayanlar en sonda pip ile
8. pipx: komut satırı araçları için
python -m pip install --user pipx # Ubuntu: sudo apt install pipx | macOS: brew install pipx pipx ensurepath # ~/.local/bin'i PATH'e ekler; terminali yeniden aç pipx install ruff # her araç kendi izole ortamında pipx run cowsay "merhaba" # kurmadan bir kez çalıştır pipx upgrade-all pipx list
| Araç | En iyi olduğu iş | Kilit dosyası |
|---|---|---|
| venv + pip | Her yerde var, öğrenme ve basit projeler | requirements.txt (freeze) |
| pip-tools | pip akışını bozmadan sağlam kilit | requirements.txt (compile) |
| uv | Hız, Python sürümü + ortam + kilit tek araçta | uv.lock |
| poetry | Kütüphane yayımlama, grup bağımlılıkları | poetry.lock |
| conda | Derlenmiş bilimsel/GPU bağımlılıkları | environment.yml (+ conda-lock) |
| pipx / uv tool | Global CLI araçları (ruff, black, httpie) | gerekmez |
9. Sık hatalar: PEP 668, SSL, proxy, sürüm çakışması
PEP 668 – error: externally-managed-environment. Ubuntu 23.04+, Debian 12+, Fedora ve Homebrew Python'ı sistem paket yöneticisine aittir; pip ile global kurulum engellenir. Çözüm her zaman bir sanal ortam (proje için) ya da pipx (araç için) kullanmaktır. --break-system-packages bayrağı adının söylediğini yapar: işletim sistemi araçlarını bozabilir.
SSL – CERTIFICATE_VERIFY_FAILED. Kurumsal ağlarda güvenlik cihazı trafiği kendi sertifikasıyla yeniden imzalar. Doğru çözüm şirketin kök sertifikasını tanıtmaktır; doğrulamayı kapatmak değil.
python -m pip install --upgrade pip # pip 24.2+ sistem sertifika deposunu (truststore) kullanır python -m pip config set global.cert C:\sertifikalar\sirket-kok.pem # ya da ortam değişkeniyle (PowerShell: $env:PIP_CERT = "...") export PIP_CERT=/etc/ssl/certs/sirket-kok.pem export REQUESTS_CA_BUNDLE=/etc/ssl/certs/sirket-kok.pem # requests/httpx için # macOS python.org kurulumunda: "Install Certificates.command" dosyasını çalıştır # Proxy: 407 Proxy Authentication Required / ProxyError export HTTPS_PROXY=http://kullanici:parola@proxy.sirket.local:8080 python -m pip install --proxy http://proxy.sirket.local:8080 pandas # Şirket içi ayna (Artifactory/Nexus) python -m pip config set global.index-url https://nexus.sirket.local/repository/pypi/simple
--trusted-host pypi.org o sunucu için sertifika doğrulamasını kapatır; araya giren herkes sahte paket verebilir. Yalnızca BT ekibinin bildiği şirket içi bir aynada, geçici olarak kullan.| Belirti | Neden | Çözüm |
|---|---|---|
ResolutionImpossible, "conflicting dependencies" | İki paket aynı bağımlılığın uyuşmaz aralıklarını istiyor | Hatadaki "requires" satırlarını oku; birini güncelle/düşür, gereksiz sabit (==) sürümleri gevşet |
| "pandas 2.2.3 has requirement numpy>=1.26, but you have numpy 1.24" | Elle kurulan eski sürüm | pip install -U numpy, sonra pip check |
No matching distribution found for X==9.9 | Sürüm yok ya da Python sürümünle uyumlu wheel yok | pip index versions X; Python sürümünü kontrol et |
ModuleNotFoundError ama "Requirement already satisfied" | Paket başka bir Python'a kurulu | python -m pip kullan; editörde yorumlayıcıyı .venv seç |
error: Microsoft Visual C++ 14.0 is required | Wheel yok, kaynak derleniyor | pip'i güncelle, wheel olan sürümü seç ya da conda |
Permission denied / [Errno 13] | Sistem klasörüne yazma | sudo pip değil: sanal ortam |
| Yükseltme sonrası her şey bozuldu | Kilit yoktu, her şey en yeni geldi | Önceki kilitten kur; pip-tools/uv ile kilit tut |
Uzun bir ResolutionImpossible çıktısında asıl bilgi "X depends on Y" satırlarındadır. Onları ayıklayıp aynı paketi kimin hangi aralıkla istediğini yan yana görmek çakışmayı hemen ortaya çıkarır:
import re
from collections import defaultdict
hata = """ERROR: Cannot install anadolu-rapor and eski-grafik because these package versions have conflicting dependencies.
The conflict is caused by:
anadolu-rapor 1.4.0 depends on numpy>=2.0
eski-grafik 0.9.1 depends on numpy<1.25
anadolu-rapor 1.4.0 depends on pandas>=2.2
ERROR: ResolutionImpossible"""
isteyenler = defaultdict(list)
for kim, surum, paket, kosul in re.findall(r"([\w.-]+) ([\d.]+) depends on ([\w.-]+)(\S*)", hata):
isteyenler[paket].append(f"{kim} {surum} -> {kosul or 'herhangi'}")
for paket, liste in isteyenler.items():
isaret = "ÇAKIŞMA ADAYI" if len(liste) > 1 else "tamam"
print(f"{paket}: {isaret}")
for satir in liste:
print(" ", satir)
uv sync --locked, uv run pytest. Kilit dosyası depodadır; CI aynı kilitle kurar, böylece "bende çalışıyor" tartışması biter. Bağımlılık güncellemeleri haftalık ayrı bir PR'da yapılır (Dependabot/Renovate), testler geçerse birleştirilir. Kurumsal ağda pip ayarları (index-url, cert) BT tarafından pip.conf/pip.ini ile dağıtılır; sen yalnızca python -m pip config list ile hangi ayarın etkin olduğunu kontrol edersin.Tekrarlanabilir ortam: kurumsal pratik
Kurumsal projelerde iki dosya birlikte yaşar: pyproject.toml geniş aralıklarla "ne istiyoruz"u söyler (pandas>=2.2,<3), kilit dosyası (uv.lock, poetry.lock ya da pip freeze çıktısı) "bugün tam olarak ne kuruldu"yu. Geliştirici esnek aralıkla çalışır, sunucu ve CI kilit dosyasıyla kurar; böylece "testler geçti ama üretimde patladı" sürprizi kalkar. Kilit dosyasını Git'e koyarsın; .venv'i koymazsın.
Üç alışkanlık daha: Birincisi, requires-python alanını yaz; ekip üyeleri 3.9 ile 3.12 arasında dağılmışsa match gibi yeni sözdizimi bir makinede çalışıp diğerinde çalışmaz. İkincisi, bağımlılıkları düzenli olarak güncelle ama tek tek: hepsini aynı anda yükseltirsen kırılan testin hangi paketten kaynaklandığını bulamazsın. Üçüncüsü, güvenlik taraması: pip audit (ya da uv/poetry'nin eşdeğeri) bilinen açıklı sürümleri listeler; Ilgaz Bank gibi düzenlemeye tabi kurumlarda bu tarama CI'da zorunlu adımdır.