Python/opt/pytok/help

From zeroincombenze
Jump to: navigation, search
Tb arrow up.jpg File:Tb opt.png File:Tb opt.png File:Tb opt.png File:Tb opt.png Lang english.png


pytok

Guida all'uso della libreria pytok


Scopo

La libreria pytok permette di estrarre da un sorgente python parti di codice con criteri di selezione e filtro. Potrebbe essere considerata un'evoluzione del comando grep del sistema operativo Linux.

La libreria permette di estrarre codice di classi (considerando anche l'ereditarietà di primo livello), codice di funzioni o righe contenenti singoli token in classi e/o funzioni. L'estrazione può essere diretta (codice con i filtri) oppure indiretta (classi e/o funzioni contenenti i filtri).

Pytok gestisce anche i modelli di Odoo.


Esempi

Il miglior esempio di utilizzo di pytok è il programma di regression test.

Si supponga un file python sample.py con il seguente codice

  1. '''
  2.     Sample for pytok unit test
  3. '''
  4.  
  5. import sys
  6.  
  7.  
  8. class Parent_Class(object):
  9.     def __init__(self):
  10.         self.myvalue = 0
  11.  
  12.     def do_something(self):
  13.         return self.myvalue
  14.  
  15.  
  16. class My_Class():
  17.     def __init__(self):
  18.         pass
  19.  
  20.     def do_something(self):
  21.         def _do_locally(val):
  22.             val -= 1
  23.             return val
  24.         val = 1
  25.         return _do_locally(val)
  26.  
  27. My_Class()
  28.  
  29.  
  30. class My_Sub_Class(My_Class):
  31.     _inherit = 'res.partner'
  32.  
  33.     def __init__(self):
  34.         pass
  35.  
  36.     def search(self):
  37.         m_obj = self.search()
  38.         return m_obj
  39.  
  40.     def browse(self, ids):
  41.         return self.browse(ids)
  42.  
  43. My_Sub_Class()
  44.  
  45.  
  46. # Follow class is just to fill white paper!
  47. class dummy:    # no useful class
  48.  
  49.     # Hidden function
  50.     def do_nothing():   # nothing to do
  51.         pass
  52.  
  53.     # Function without class call
  54.     @staticmethod
  55.     def do_public():
  56.         return 0
  57.  
  58.  
  59. class My_Child(Parent_Class):
  60.  
  61.     uresponse = 42
  62.  
  63.     @classmethod
  64.     def universal_response(cls):
  65.         return cls.uresponse
  66.  
  67.     def do_something(self):
  68.         v = super(My_Child, self).do_something()
  69.         if v == 0:
  70.             return self.universal_response()
  71.  
  72.     def do_think_different(self, value):
  73.         if value > 0:
  74.             def _think_positive(value):
  75.                 return value
  76.         elif value < 0:
  77.             def _think_negative(value):
  78.                 return 0
  79.             return _think_negative(value)
  80.         else:
  81.             def _think_positive(value):
  82.                 value += 1
  83.                 return value
  84.         return _think_positive(value)
  85.  
  86.  
  87. def main():
  88.     # tool main
  89.     sts = dummy.do_public()
  90.     if sts == 0:
  91.         A = My_Class()
  92.         sts = A.do_something()
  93.     if sts == 0:
  94.         sts = Parent_Class().do_something()
  95.     if sts == 0:
  96.         sts = My_Child().do_something() - 42
  97.     if sts == 0:
  98.         M = My_Child()
  99.         sts = 1 - M.do_think_different(1)
  100.     if sts == 0:
  101.         sts = 1 - M.do_think_different(0)
  102.     if sts == 0:
  103.         sts = M.do_think_different(-1)
  104.     return sts
  105.  
  106.  
  107. if __name__ == "__main__":
  108.     sts = main()
  109.     if sts:
  110.         raise ValueError
  111.     sys.exit(sts)

Il programma è perfettamente funzionante anche se non produce alcun effetto.


Tutto il sorgente

Esempio per estrarre il sorgente senza filtri

src = pytok.open('sample.py')
src.parse_src()
print src.tostring()


Classe con ereditarietà

Esempio per estrarre una classe comprensiva della classe padre.

src = pytok.open('sample.py')
src.decl_classes_2_search('my_sub')
src.parse_src()
print src.tostring()


produce il seguente output

  1. class My_Class():
  2.     def __init__(self):
  3.         pass
  4.  
  5.     def do_something(self):
  6.         def _do_locally(val):
  7.             val -= 1
  8.             return val
  9.         val = 1
  10.         return _do_locally(val)
  11.  
  12. My_Class()
  13.  
  14.  
  15. class My_Sub_Class(My_Class):
  16.     _inherit = 'res.partner'
  17.  
  18.     def __init__(self):
  19.         pass
  20.  
  21.     def search(self):
  22.         m_obj = self.search()
  23.         return m_obj
  24.  
  25.     def browse(self, ids):
  26.         return self.browse(ids)
  27.  
  28. My_Sub_Class()

Come si vede è sufficiente una parte del nome della classe per estrarre sia il padre che gli eventuali figli.

Riferimento tecnico

decl_classes_2_search(classes)

Dichiara le classi da cercare. Da usare dopo new o open.

Sintassi:

src = pytok.open('sample.py')
decl_classes_2_search('my_class,parent_class()')

Le classi devono essere separate da virgola.

Ogni nome può essere inserito seguito dalle parentesi. Se le parentesi sono assenti il nome fornito è considerato una parte del nome della classe da cercare; se le parentesi sono inserite la ricerca è effettuata per nome esatto. Esempio my_ trova my_class mentre parent_class() trova esclusivamente la classe parent_class.

Se la classe eredita anche la classe padre è trovata. Se la classe è ereditata, anche le classi figlie sono trovate.


decl_funs_2_search(functions)

Dichiara le funzioni da cercare. Da usare dopo new o open.

Sintassi:

src = pytok.open('sample.py')
decl_funs_2_search('my_fun,your_fun()')

I nomi funzione devono essere separate da virgola.

Ogni nome può essere inserito seguito dalle parentesi. Se le parentesi sono assenti il nome fornito è considerato una parte del nome della funzione da cercare; se le parentesi sono inserite la ricerca è effettuata per nome esatto. Esempio my_ trova my_fun mentre your_fun() trova esclusivamente la classe your_fun.

Sono cercate esclusivamente le funzioni pubbliche richiamabili dalla classe. Le sottofunzioni di una funzione non sono trovate. Ad esempio in questo pezzo di codice:

    def do_something(self):
        def _do_locally(val):

la funzione _do_locally non è mai trovata direttamente ma soltanto se trovata la funzione do_something


decl_model_2_search(model)

Funzione speciale valida soltanto per sorgenti Odoo. Dichiara il modello da cercare. Da usare dopo new o open.

Sintassi:

src = pytok.open('sample.py')
decl_model_2_search('res.users,res.partner')

I nomi modello devono essere separate da virgola. L'uso del modello abilita la ricerca indiretta, ovvero le classi e/o le funzioni contenenti i modelli.


decl_options(output=None, no_num_line=None)

Dichiara alcune opzioni di visualizzazione. Da usare dopo new o open.

Sintassi:

src = pytok.open('sample.py')
src.decl_options(params)

Le opzioni possibili sono:

    prm = {}
    prm['output'] = None          # contiene una funzione per estrarre o formattare l'output
    prm['no_num_line'] = False    # se True l'output è fornita senza numeri di riga
    prm['in_class'] = '.*'        # lista classi da ricercare, separate da virgola; vedi decl_classes_2_search
    prm['infun'] = '.*'           # lista funzione da ricercare, separate da virgola; vedi decl_funs_2_search
    prm['tokens'] = '.*'          # lista token da cercare, separati da virgola; vedi decl_tokens_2_search
    prm['model'] = None           # Ricerca modello Odoo
    prm['no_header'] = False      # se True non visualizza le intestazione delle funzioni e delle classi

decl_tokens_2_search(tokens)

Dichiara i testi da cercare. Da usare dopo new o open.

Sintassi:

src = pytok.open('sample.py')
decl_funs_2_tokens('return,raise')

I testi devono essere separate da virgola.


new(text=None)

Apre una lista di istruzioni python e restituisce un oggetto per le successive elaborazioni.

Sintassi:

SRC = {}
SRC[0] = 'def myfun():'
SRC[1] = '    pass'
src = pytok.new(text=SRC)


open(file)

Apre un file python e restituisce un oggetto per le successive elaborazioni.

Sintassi:

src = pytok.open('sample.py')


tostring(output=None)

Fornisce l'output di testo del codice cercato.

Sintassi:

src = pytok.open('sample.py')
decl_classes_2_search('my_class,parent_class()')
decl_funs_2_search('my_fun,your_fun()')
res = src.tostring()

L'output può essere inviato ad una funzione, se passata o se fornita in decl_options.


version

Proprietà che restituisce la versione della libreria. Disponibile dalla V0.2.5

Sintassi:

print pytok.version