453
453
from kivy .logger import Logger
454
454
from kivy .utils import OrderedDict , QueryDict
455
455
from kivy .cache import Cache
456
- from kivy import kivy_data_dir
456
+ from kivy import kivy_data_dir , require
457
+ from kivy .lib .debug import make_traceback
458
+
457
459
458
460
trace = Logger .trace
459
461
global_idmap = {}
467
469
lang_keyvalue = re .compile ('([a-zA-Z_][a-zA-Z0-9_.]*\.[a-zA-Z0-9_.]+)' )
468
470
469
471
470
- def precompile_value (name , value ):
472
+ def precompile_value (name , value , line = 1 , parser = None ):
471
473
# if it's an id, we don't need to compile, the value is the id.
472
474
if name == 'id' :
473
475
return value
@@ -480,18 +482,18 @@ def precompile_value(name, value):
480
482
# if we don't detect any string/key in it, we can eval and give the
481
483
# result
482
484
if re .search (lang_key , tmp ) is None :
483
- return (None , eval (value ), value )
485
+ return (None , eval (value ), value , line + 1 , parser )
484
486
485
487
# ok, we can compile.
486
- code = compile (value , '<string>' , mode )
488
+ code = compile (value , parser . filename or '<string>' , mode )
487
489
488
490
# now, detect obj.prop
489
491
# first, remove all the string from the value
490
492
tmp = re .sub (lang_str , '' , value )
491
493
# detect key.value inside value
492
494
kw = re .findall (lang_keyvalue , tmp )
493
495
494
- return (kw , code , value )
496
+ return (kw , code , value , line + 1 , parser )
495
497
496
498
497
499
class ParserError (Exception ):
@@ -529,13 +531,10 @@ def __init__(self, **kwargs):
529
531
self .sourcecode = []
530
532
self .objects = []
531
533
self .directives = []
534
+ self .filename = kwargs .get ('filename' , None )
532
535
content = kwargs .get ('content' , None )
533
- self .filename = filename = kwargs .get ('filename' , None )
534
- if filename :
535
- content = self .load_resource (filename )
536
536
if content is None :
537
- raise ValueError ('No content passed. Use filename or '
538
- 'content attribute.' )
537
+ raise ValueError ('No content passed' )
539
538
self .parse (content )
540
539
541
540
def execute_directives (self ):
@@ -633,7 +632,7 @@ def precompile_objects(self, objects):
633
632
'canvas.after' ):
634
633
self .precompile_objects (value [0 ])
635
634
continue
636
- value [0 ] = precompile_value (key , value [0 ])
635
+ value [0 ] = precompile_value (key , value [0 ], value [ 1 ], value [ 2 ] )
637
636
638
637
def parse_version (self , line ):
639
638
'''Parse the version line.
@@ -648,9 +647,9 @@ def parse_version(self, line):
648
647
'#:kivy <version>' )
649
648
650
649
version = content [6 :].strip ()
651
- if version != '1.0' :
652
- raise ParserError ( self , ln , 'Only Kivy language 1.0 is supported '
653
- ' (<%s> found)' % version )
650
+ if len ( version . split ( '.' )) == 2 :
651
+ version += '.0 '
652
+ require ( version )
654
653
if __debug__ :
655
654
trace ('Parser: Kivy version is %s' % version )
656
655
@@ -792,9 +791,16 @@ def _eval_center(boxsize, center):
792
791
793
792
def custom_callback (* largs , ** kwargs ):
794
793
element , key , value , idmap = largs [0 ]
794
+ __kvlang__ = value
795
795
locals ().update (idmap )
796
796
args = largs [1 :]
797
- exec value [1 ]
797
+ try :
798
+ exec value [1 ]
799
+ except :
800
+ exc_info = sys .exc_info ()
801
+ traceback = make_traceback (exc_info )
802
+ exc_type , exc_value , tb = traceback .standard_exc_info
803
+ raise exc_type , exc_value , tb
798
804
799
805
800
806
def create_handler (element , key , vd , idmap ):
@@ -960,7 +966,8 @@ def load_string(self, string, **kwargs):
960
966
kwargs .setdefault ('rulesonly' , False )
961
967
self ._current_filename = kwargs .get ('filename' , None )
962
968
try :
963
- parser = Parser (content = string )
969
+ parser = Parser (content = string , filename = kwargs .get (
970
+ 'filename' , None ))
964
971
root = self .build (parser .objects )
965
972
if kwargs ['rulesonly' ] and root :
966
973
filename = kwargs .get ('rulesonly' , '<string>' )
0 commit comments