[Gelistirici] PiSi'de "from module import X"

Faik Uygur faik at pardus.org.tr
19 Nis 2007 Per 22:02:44 EEST


On Thursday 19 April 2007 00:19:33 Barış Metin wrote:
> Selam,

Selam,

> mymodule.py adında bir modülümüz olsun. İçeriği şu:
>
> def karpuz():
>     print "round 1"
>
> In [1]: from mymodule import karpuz
> In [2]: karpuz()
> round 1
>
> Gidip mymodule.py'yi düzenleyelim. Yeni içerik:
> def karpuz():
>     print "round 2"
>
> In [3]: import sys
> In [4]: reload(sys.modules[karpuz.__module__])
> Out[4]: <module 'mymodule' from 'mymodule.py'>
> In [5]: exec("from %s import karpuz" % karpuz.__module__)
> In [6]: karpuz()
> round 2
>
> Faik, bu işimizi çözüyor mu? Görebildiğim kadarı ile başka yöntemleri de
> var ama en basitçe uygulanabilecek bu. Bu işi otomatik yapabiliriz tabi,
> global içerisinde __module__'ü farklı/istediğimiz olan tüm nesneleri bu
> şekilde reload ettiririz...

Otomatikleştirme kısmının nasıl yapılacağını tam anlayamadım. globals() içinde 
tipi function olan herşeyin modülünü mü reload edeceğiz. Bir de exec leri 
nasıl otomatikleştiriyoruz?

Bu kullanım biraz garip görünüyor ama. İlginç bir çözüm. Reload geçen hiç bir 
yerde böyle bir şey görmedim. Önerilerin çoğu "from import" kullanmayın 
şeklindeydi. Bulduğum en iyi kaynaklar şunlar:

http://www.leftworld.net/online/Python/lpython_snode60.html
http://pyunit.sourceforge.net/notes/reloading.html
http://effbot.org/zone/import-confusion.htm

reload işi karmaşık bir iş. pyunit'in sorunlarına ve nasıl aştıklarına 
bakabilirsin. Şu an pisi içerisinde bu yönteme yakın bir şeyler yapıyoruz.
 
Mevcut kodun üstüne "from import" lar için böyle bir çözümde eklenince
ne olur bilemiyorum. Sorun olmaz çalışır diyorsan ciddi ciddi bu kısmı yazmak 
ister misin diye sorayım. reload işine bir türlü güveniyorum, her an bir 
yerde sorun çıkaracakmış gibi rahatsız ediyor.

> PS: Reload işini PiSi dışarısında yapmak konusunu biliyorum, bu ilk "from
> import" sorunumuz için bir öneri şimdilik...

a,b,c modüllerini kullanan dışarıdan bir d'nin a,b,c yi reload etmesi mantıklı 
geliyor. Bu işin a,b,c modüllerinden birinin içinde yapılması bir acayip... 
Şu anki durum bu.

> PS2: Daha önce konuşulan ve Çağlar'ın da toplantıda bahsettiği reload'un
> bir wrapper tarafından yapılması fikri sıcak gelmemeye başladı. RPM bunu
> bir wrapper ile çözüyor ama Python gibi bir dil kullanmıyor :).

wrapper'dan kasıt farklı bir şey mi? Benim aklımdaki örneğin pisi-cli'nin, 
pisi modüllerini dışarıdan kullanan bir uygulama olarak bu pisi modüllerini 
reload etmesi doğru bir çözüm görünüyor. Aynı şekilde package manager'da 
dışardan bu modülleri kullanan bir uygulama olarak reload etmeli. Şu an pisi 
kendi modülleri içinde upgrade akışında bu işi yapmaya çalışıyor.

Keşke kurtulabilsek reload  gereksiniminden. Şöyle bir yöntem olabilir mi? Çok 
mu rahatsız edici olur kullanıcı açısından? 

pisi.api.init dosya sisteminde db versiyonu kontrolü yapıyor normalde. Eski 
kaldıysa dosya sistemindeki db versiyonu rebuild-db çalıştırın diyor ve 
kapanıyor.

Db versiyonu ileri ve pisi içindeki db versiyonu eski ise. Yeni pisi lazım 
gibi bir uyarı veriyor ve kapanıyor.

rebuilddb'nin kullanılma amacı yalnızca pisi db versiyonu'nun, pisi'nin yeni 
sürümünde değişmesinden dolayı. Bu işi otomatik yaptırmak için (konsolda elle 
çalıştırılmasın diye) upgradelerde bir kontrol yapıp reload yapıyoruz, 
ardından rebuild yapıyoruz. Şimdi upgrade sonunda bunu yapmasak. Ne 
olacak? pisi işini bitirdi ve çıktı. Bir sonraki pisi açılışında, pisi benim 
db'im hede höd diyecek. Bunu demesin ve pisi.api.init diyene bir Exception 
üretsin. 

Bunu gören pisi-cli de otomatik rebuild-db sini yapsın. Bu durumda reload'a 
gerek olmuyor. Package manager için de, her işlem sonrası finalize-init 
yapıyor zaten. Init'de bu exception'ı alırsa, pisi güncellenmiş, paket 
yöneticisini lütfen açıp, kapatın gibi bi şey diyebilir. Yine reload'a gerek 
kalmadan yeni pisi ile çalıştığından rebuild-db yi otomatik yapsın.

Bunun bir kötü yanı var tabi. ipython'dan ya da paket yöneticisi dışında bir 
yerden, api.init çalıştıran birine bu Exception biraz abes kaçıyor gibi. Bir 
de yarı otomatikmiş gibi duruyor. :)

- Faik



Gelistirici mesaj listesiyle ilgili daha fazla bilgi