---
title: 'Bağımlılık Bildirimi'
source: 'https://academia.sh/tr/kurslar/python-projeleri/bagimlilik-bildirimi'
course: 'Python Projeleri: Paketleme ve Test'
language: tr
updated: '2026-08-17T18:10:31+00:00'
license: 'CC BY-SA 4.0'
---

# Bağımlılık Bildirimi

Aynı bildirim çözümleme stratejisi değiştiğinde 2 ayrı sürüm kümesi verir ve kilit dosyası sayıyı 1'e indirir; depo görüntüsü de değiştiğinde bildirimle yapılan dört kurulum 3 ayrı küme verirken kilitli dördü tek küme kalır.

Önceki ders bir sınır çizdi ve sınırın payını ölçtü: yalıtılmış bir sitede kurulum sırası
ile komşu projeler elendi, beş ayrı sonuç bire indi. O ölçüm bir şeyi sabit tutarak elde
edildi — çözümleme kuralı hep aynıydı, hep en yeni uygun sürüm seçildi.

Bu ders o sabiti serbest bırakır. Sorusu şudur: **aynı bildirim, tek başına kaç ayrı sürüm
kümesi belirtiyor?** Bildirim projenin yazdığı tek şeydir ve değişmez; değişen, onu okuyan
tarafın kuralıdır. Yanıt ölçülecek, sonra bir dosyaya yazılıp ölçüm yinelenecek.

## Bildirim Bir Aralık Söyler

**Bağımlılık bildirimi**, projenin meta verisinde duran ve hangi paketlere hangi sürüm
aralığında ihtiyaç duyulduğunu söyleyen listedir. Meta verinin kendisi bundan fazlasını
taşır: projenin adı, kendi sürümü, giriş noktaları, isteğe bağlı bağımlılık grupları. Bu
dersin ilgilendiği alan yalnız bağımlılık listesidir.

Bildirimin yazılış biçimi kritik bir ayrım taşır. Bir paket için yazılan şey neredeyse hiç
tek bir sürüm değildir; bir **aralıktır** — en küçük kabul edilen sürüm ve üstünde artık
kabul edilmeyen sürüm. Bunun bir nedeni var: tek sürüme sabitlenmiş bir bildirim, o paketi
kullanan başka bir paketle bir araya gelemez. Aralık, bir araya gelebilmenin koşuludur.

Bedeli de aynı yerden gelir. Bir aralık, içine düşen her sürümü meşru kılar. Bildirimi
okuyan taraf aralıktan **bir** sürüm seçmek zorundadır ve bu seçimi yapan kural bildirimde
yazmaz. Kural, aralığı okuyan **paket yöneticisinin** kendi **çözümleme stratejisidir
(resolution strategy)**.

Bu derste iki strateji karşılaştırılır: **en yeni** ve **en eski uyumlu**. İkisi de
bildirime uyar; ikisi de meşrudur. Stratejiler ve davranışları derste **modellenmiştir**;
hiçbir ürün adı yazılmaz ve gerçek kurulum yapılmaz.

## Kilit Nedir, Ne Değildir

**Kilit dosyası (lock file)**, bir çözümlemenin sonucunu satır satır yazan belgedir:
aralık değil, seçilen tam sürümler. Bildirim insanın yazdığı istektir, kilit makinenin
ürettiği karardır. İkisi ayrı belgelerdir ve ikisi de sürüm denetimine konur — önceki
dersteki ortamın tersine, çünkü ortam bir yapıt, kilit ise bir karardır.

Kilidin ne olmadığını söylemek daha önemli. Kilit, çözümlemeyi ortadan kaldırmaz. Kilit
dosyasının kendisi **bir çözümlemenin çıktısıdır**; üretilmesi için aralıkların bir kez
okunması, bir stratejinin uygulanması ve bir kümenin seçilmesi gerekir. Kilidin yaptığı şey
o işi bir kez yaptırıp sonucunu **yazıya geçirmektir**. Sonraki kurulumlar çözümleme
yapmaz, yazılanı okur.

Bu ayrım ölçümde iki satır olarak görünür: kilit dosyasıyla yapılan iki kurulum, iki ayrı
strateji istense bile aynı kümeyi verir. Strateji artık okunmuyordur.

Ölçümün varsayımları:

- **OB12** — Depo, bildirim ve çözümleme işlevi ortak tanımdan birebir alınır; ders
  ikisinin de davranışını değiştirmez.
- **OB13** — Depo bir işlev parametresi haline getirilmiştir ve öntanımlı değeri ortak
  tanımın deposudur. Bağlayıcı sayılar öntanımlı depoyla üretilir.
- **OB14** — Bildirim bir aralıktır: en küçük sürüm dahil, en büyük sürüm hariç.
- **OB15** — İki strateji vardır: **en yeni**, uygun adayların sonuncusunu; **en eski
  uyumlu**, ilkini seçer. İkisi de bildirime uyar.
- **OB16** — Kâhin kurgudur: hangi sürümlerin yayımlandığını ve bildirimin ne kabul ettiğini
  biz yazdık; her satırın doğru sonucu ölçmeden bilinir.
- **OB17** — Kilit, bir çözümlemenin sonucunun kopyasıdır. Kilit varken çözümleme
  çağrılmaz; bu, modelde `kur` işlevinin tek dallanmasıdır.
- **OB18** — Ölçümde kilit **en yeni** stratejisinin sonucundan üretilir. Başka bir
  stratejiden üretilseydi kilitli satırlar o kümeyi gösterirdi; değişmeyecek olan, kilitli
  kurulumların **kaç ayrı sonuç** verdiğidir.
- **OB19** — İkinci depo görüntüsü, ilk depoya sonradan yayımlanmış sürümler eklenerek
  türetilir. Bildirim değişmez, depo değişir; eklenen sürümler bildirimin aralığına düşer.
- **OB20** — Bu derste paketler birbirini gerektirmez; her paket bağımsız seçilir. Geçişli
  gereklerin ve çakışmanın ne yaptığı sonraki dersin konusudur.
- **OB21** — Sürüm numaraları kurgu paketlerin kurgu sürümleridir; gerçek bir paketin ya da
  aracın sürümü değildir.
- **OB22** — **Gerçek kurulum yapılmaz, gerçek paket indirilmez.** Kurulum, seçilen sözlüğün
  döndürülmesidir.
- **OB23** — Süre ölçülmez. Sayılan şey **ayrı sürüm kümesi**, yani ayrı sonuçtur.

## Ölçüm

```python
"""Bildirim bir aralik belirtir: strateji ve depo goruntusu kac ayri kume veriyor."""

DEPO = {
    "olcum": [(1, 0), (1, 1), (1, 2), (2, 0)],
    "rapor": [(0, 9), (1, 0), (1, 1)],
    "ortak": [(3, 0), (3, 1), (3, 2), (4, 0)],
}
BILDIRIM = {"olcum": ((1, 0), (2, 0)), "rapor": ((1, 0), (2, 0)),
            "ortak": ((3, 0), (4, 0))}
# Ayni depo, sonradan yayimlanmis surumlerle: bildirim degismedi, depo degisti.
YENI = {"olcum": [(1, 3)], "rapor": [(1, 2)], "ortak": [(3, 3)]}
SONRA = {p: sorted(DEPO[p] + YENI[p]) for p in DEPO}
PAKETLER = ("olcum", "ortak", "rapor")


def uygun(paket, depo=DEPO):
    alt, ust = BILDIRIM[paket]
    return [s for s in depo[paket] if alt <= s < ust]


def coz(strateji, depo=DEPO):
    """Ayni bildirimi iki ayri strateji cozer."""
    secim = {}
    for paket in sorted(BILDIRIM):
        adaylar = uygun(paket, depo)
        secim[paket] = adaylar[-1] if strateji == "en yeni" else adaylar[0]
    return secim


def kilit(secim):
    """Kilit, cozumlemenin sonucunu sabitler."""
    return dict(secim)


def kur(kilit_dosyasi=None, strateji="en yeni", depo=DEPO):
    return kilit_dosyasi if kilit_dosyasi else coz(strateji, depo)


def yazim(secim):
    return " ".join(f"{'.'.join(map(str, secim[p])):>7s}" for p in PAKETLER)


yeni, eski = coz("en yeni"), coz("en eski")
k = kilit(yeni)
print(f"{'kurulum':<26s} {'olcum':>7s} {'ortak':>7s} {'rapor':>7s}")
for ad, secim in (("strateji: en yeni", yeni), ("strateji: en eski", eski),
                  ("kilit dosyasıyla", kur(k)), ("kilit, başka strateji", kur(k, "en eski"))):
    print(f"{ad:<26s} " + yazim(secim))
ayri = len({tuple(sorted(s.items())) for s in (yeni, eski)})
ayri_kilitli = len({tuple(sorted(kur(k, st).items())) for st in ("en yeni", "en eski")})
print(f"aynı bildirim, stratejiye göre {ayri} ayrı küme; kilitle {ayri_kilitli}")

print()
print(f"{'depo görüntüsü / rejim':<26s} {'olcum':>7s} {'ortak':>7s} {'rapor':>7s}")
kurulumlar = []
for depo_ad, depo in (("ilk depo", DEPO), ("sonraki depo", SONRA)):
    for st in ("en yeni", "en eski"):
        secim = kur(None, st, depo)
        kurulumlar.append(secim)
        print(f"{depo_ad + ', ' + st:<26s} " + yazim(secim))
kilitli = [kur(k, st, depo) for depo in (DEPO, SONRA) for st in ("en yeni", "en eski")]
print(f"{'kilit dosyasıyla, dördü de':<26s} " + yazim(kilitli[0]))
print(f"iki depo görüntüsü ve iki strateji, dört kurulum: bildirimle "
      f"{len({tuple(sorted(s.items())) for s in kurulumlar})} ayrı küme, "
      f"kilitle {len({tuple(sorted(s.items())) for s in kilitli})}")

print()
uretim = coz("en yeni")
print(f"kilit çözümlemeden üretilir: kilit == en yeni çözümlemesi -> "
      f"{kilit(uretim) == uretim}")
print("kilit sonraki depoda yeniden üretilirse: " + yazim(kilit(coz("en yeni", SONRA))))
```

```
kurulum                      olcum   ortak   rapor
strateji: en yeni              1.2     3.2     1.1
strateji: en eski              1.0     3.0     1.0
kilit dosyasıyla               1.2     3.2     1.1
kilit, başka strateji          1.2     3.2     1.1
aynı bildirim, stratejiye göre 2 ayrı küme; kilitle 1

depo görüntüsü / rejim       olcum   ortak   rapor
ilk depo, en yeni              1.2     3.2     1.1
ilk depo, en eski              1.0     3.0     1.0
sonraki depo, en yeni          1.3     3.3     1.2
sonraki depo, en eski          1.0     3.0     1.0
kilit dosyasıyla, dördü de     1.2     3.2     1.1
iki depo görüntüsü ve iki strateji, dört kurulum: bildirimle 3 ayrı küme, kilitle 1

kilit çözümlemeden üretilir: kilit == en yeni çözümlemesi -> True
kilit sonraki depoda yeniden üretilirse:     1.3     3.3     1.2
```

## İki Küme, Sonra Bir

Üst tablonun ilk iki satırı kursun ikinci iddiasını taşıyor. Aynı bildirim, aynı depo, aynı
üç paket: strateji **en yeni** olduğunda `1.2 / 3.2 / 1.1`, **en eski uyumlu** olduğunda
`1.0 / 3.0 / 1.0`. **2 ayrı sürüm kümesi.**

İki küme arasında hiçbir yerde bir hata yok. Bildirim ikisini de kabul ediyor; ikisi de
projenin yazdığı isteğe uyuyor. Ama bunlar aynı kurulum değil. Üç paketin üçü de ayrı
sürümde; kodun karşılaşacağı davranış, düzeltilmiş kusurlar ve eklenmiş yöntemler ayrı.
"Bildirim aynı, o hâlde kurulum aynı" cümlesi ölçümün çürüttüğü cümledir.

İkisi arasında bir üstünlük sıralaması da yok, çünkü ikisi ayrı şey sınıyor. **En yeni**
düzeltmeleri getirir, ama bildirimin üst sınırına en yakın davranışı getirdiği için
projenin en az sınadığı sürümleri seçer. **En eski uyumlu** tam tersini yapar: bildirimin
alt ucunun gerçekten çalıştığını sınar. Bir aralığın alt sınırı çoğu zaman kopyalanarak
yazılmıştır ve hiç denenmemiştir; onu seçen bir kurulum, bildirimin yalan söyleyip
söylemediğini ortaya çıkarır. Ölçümün söylediği şey hangisinin iyi olduğu değil, **ikisinin
aynı kurulum olmadığıdır.**

Alt iki satır kilidi devreye sokuyor. Kilit dosyasıyla yapılan kurulum `1.2 / 3.2 / 1.1`
veriyor; kilit dosyası **ve** başka bir strateji istendiğinde de aynı küme geliyor.
**Kilitle 1 ayrı sonuç.** Dördüncü satır tek başına şunu söylüyor: strateji artık okunmuyor,
çünkü okunacak bir aralık kalmadı. Karar zaten verilmiş ve yazılmış.

## Depo Zamanla Değişir

İkinci tablo değişkeni bir tane artırıyor. Bildirim yine aynı, ama depo bir sonraki
görüntüsünde: aralığa düşen üç yeni sürüm yayımlanmış.

Bildirimle yapılan dört kurulum **3 ayrı küme** veriyor. `en yeni` stratejisi iki depo
görüntüsünde iki ayrı küme üretiyor — `1.2 / 3.2 / 1.1` ve `1.3 / 3.3 / 1.2` — çünkü "en
yeni" sabit bir sürüm değil, **deponun o anki durumuna bağlı bir işlevdir**. `en eski uyumlu`
ise iki görüntüde de aynı kümeyi veriyor; aralığın alt ucu deponun büyümesinden etkilenmiyor.

Bu satır, bildirimin taşıdığı belirsizliğin iki eksenli olduğunu gösteriyor: **kim çözüyor**
ve **ne zaman çözüyor**. Aynı bildirim aynı stratejiyle bile iki ayrı zamanda iki ayrı küme
verebilir. Kurulumun tarihi, çıktının bir parçasıdır.

Kilitli dört kurulum yine **1 ayrı sonuç** veriyor. Kilit her iki ekseni birden kapatıyor,
çünkü yazılan şey bir kural ya da bir aralık değil, sürümlerin kendisidir. Bu, iki tablonun
birlikte okunmasını gerektiren bir sonuçtur: bildirimle yapılan kurulumların sayısı
arttıkça ayrı sonuç sayısı da artıyor — iki kurulumda iki, dört kurulumda üç — kilitli
tarafta ise kurulum sayısı ne olursa olsun sayı **1**'de duruyor.

Son iki satır kilidin nereden geldiğini gösteriyor. Kilit, `en yeni` çözümlemesinin
sonucuna eşittir — üretilmesi için çözümleme koşmuştur. Ve aynı kilit sonraki depoda
yeniden üretilirse `1.3 / 3.3 / 1.2` çıkar. Yani kilit dondurulmuş bir çözümlemedir;
çözümleme yeniden koşturulduğunda dondurduğu şey de değişir.

## Kilidin Kapsamı

Bildirim ile kilidin uzunlukları neredeyse hiç aynı değildir, ve nedeni ölçümün dışında
kalan bir yerdedir.

Bildirim projenin **doğrudan** istediklerini yazar. Kurulan küme ise çoğu zaman daha
büyüktür, çünkü istenen her paketin kendi bildirimi vardır ve o bildirim de başka paketler
getirir. Bunlara **geçişli bağımlılık** denir. Projenin kodu onları hiç anmaz, ama koşum
anında sitede dururlar ve davranışa katılırlar. Kilit dosyası kurulan kümenin **tamamını**
yazar; doğrudan istenenleri değil, siteye giren her paketi. Bu yüzden kilit bildirimden çok
daha uzundur ve elle yazılacak bir belge değildir.

Bu dersin kurgusunda paketler birbirini gerektirmiyor, bu yüzden iki küme çakışıyor ve
tablolar üç satırla okunabiliyor. Farkın açıldığı yer sonraki dersin ölçümüdür.

Kilidin ikinci alanı sürüm adının altına bakar. Bir sürüm numarası bir **etikettir**; o
etiketin altındaki içeriğin zaman içinde değişmediğini kendi başına söylemez. Kilit
dosyaları bu yüzden sürümün yanına bir **içerik özeti** yazabilir ve kurulum sırasında
indirileni özetle karşılaştırabilir. Sürüm adı eşleşip özet eşleşmediğinde ortaya çıkan
şey bir sürüm sorunu değil, aynı adın iki ayrı içerik taşıması sorunudur — ve bu, sürüm
numarasının hiçbir zaman göremeyeceği bir ayrı sonuçtur.

Üçüncüsü kapsamın kendisidir. Bir projenin bildiriminde çoğu zaman birden çok grup bulunur:
koşum için gerekenler, sınama için gerekenler, belge üretimi için gerekenler. Bunlar ayrı
kümelerdir ve ayrı kurulur. Bir kilidin hangi grupları kapsadığı yazılı değilse, aynı kilit
iki ayrı kurulumda iki ayrı küme kurdurur — hem de her iki kurulum da kilide uymuş olur.
Kilit yalnız sürümleri değil, **hangi soruya yanıt verdiğini** de sabitlemek zorundadır.

## Kilit Çözümlemeyi Ortadan Kaldırmaz

Ölçümün bütün satırları tek bir cümlede toplanır: **kilit çözümlemeyi ortadan kaldırmaz;
kararı bir kez verdirir ve yazıya geçirir.**

Bunun üç doğrudan sonucu var. Birincisi, kilit bir güvence değil bir **kayıttır**; ne kadar
iyi bir kümenin dondurulduğunu söylemez, yalnız hangi kümenin dondurulduğunu söyler. Kötü
bir çözümleme de aynı sadakatle kilitlenir.

İkincisi, kilidin yenilenmesi kaçınılmaz bir iştir. Aralık yeni sürümleri kabul ediyor ama
kilit onları getirmiyorsa, proje bildiriminin izin verdiği bir yerde değil, geçmişte bir
noktada duruyordur. Bu geçmiş nokta bilinçli seçilmişse bir karardır; farkında olunmadan
kalınmışsa bir birikmedir. İkisini ayıran tek şey, kilidin ne zaman ve neden yenilendiğinin
yazılı olmasıdır.

Üçüncüsü, bildirim ile kilidin **birbirinden sapabilmesidir**. Kilit elle düzenlenirse ya da
bildirim değiştirilip kilit yenilenmezse, iki belge iki ayrı şey söyler ve kurulum
hangisinin okunduğuna göre ayrı sonuç verir. Ölçümün son satırı bunun sınamasını veriyor:
kilit, aynı bildirimden aynı stratejiyle yeniden üretildiğinde kendisiyle aynı çıkmalıdır.
Çıkmıyorsa ya depo değişmiştir ya da belgelerden biri elle dokunulmuştur — ve hangisi
olduğu, deponun görüntüsüne bakılarak ayırt edilir.

## Özet

- **Bağımlılık bildirimi** bir sürüm değil bir **aralık** söyler; aralık, başka paketlerle
  bir araya gelebilmenin koşuludur ve bedeli seçimin bildirimin dışında yapılmasıdır.
- Aynı bildirim, çözümleme stratejisi değiştiğinde **2 ayrı sürüm kümesi** verir:
  `1.2 / 3.2 / 1.1` ile `1.0 / 3.0 / 1.0`. İkisi de bildirime uyar.
- **Kilit dosyası** çözümlemenin sonucunu tam sürümlerle yazar; kilitli kurulum strateji
  değişse bile **1 ayrı sonuç** verir, çünkü okunacak aralık kalmamıştır.
- Depo görüntüsü de değiştiğinde bildirimle yapılan dört kurulum **3 ayrı küme** verir;
  belirsizlik iki eksenlidir: kim çözüyor ve ne zaman çözüyor.
- Kilit, doğrudan istenenleri değil **kurulan kümenin tamamını** yazar; hangi grupları
  kapsadığını da yazmazsa aynı kilit iki ayrı küme kurdurabilir.
- **Kilit çözümlemeyi ortadan kaldırmaz; kararı bir kez verdirir ve yazıya geçirir.** Kilit
  bir güvence değil bir kayıttır ve yenilendiğinde dondurduğu küme de değişir.

## Sonraki Adım

Bu dersin ölçümünde paketler birbirinden bağımsız seçildi: her paket kendi aralığından
alındı ve seçimler birbirine hiç bakmadı. Gerçek bir kümede paketlerin kendi bildirimleri
vardır ve bunlar birbiriyle çelişebilir. Sonraki ders o durumu ölçer: aynı bildirim, paket
gerekleri de hesaba katıldığında hangi kümeleri veriyor, bir strateji tutarsız bir küme
seçtiğinde bu nereden görülüyor, ve hiçbir tutarlı küme yoksa çözümleme ne döndürüyor.
