parser.py (pymol-v1.8.6.0.tar.bz2) | : | parser.py (pymol-v2.1.0.tar.bz2) | ||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
#Z* ------------------------------------------------------------------- | #Z* ------------------------------------------------------------------- | |||
# parser.py | # parser.py | |||
# Python parser module for PyMol | # Python parser module for PyMol | |||
# | # | |||
from __future__ import absolute_import | from __future__ import absolute_import | |||
# Don't import __future__.print_function | # Don't import __future__.print_function | |||
class SecurityException(Exception): | ||||
pass | ||||
SCRIPT_TOPLEVEL = 'toplevel' | ||||
if __name__=='pymol.parser': | if __name__=='pymol.parser': | |||
import pymol | import pymol | |||
import traceback | import traceback | |||
import re | import re | |||
import glob | import glob | |||
import sys | import sys | |||
import os | import os | |||
import __main__ | import __main__ | |||
from . import parsing | from . import parsing | |||
from . import colorprinting | ||||
from .cmd import _feedback,fb_module,fb_mask,exp_path | from .cmd import _feedback,fb_module,fb_mask,exp_path | |||
QuietException = parsing.QuietException | QuietException = parsing.QuietException | |||
CmdException = pymol.CmdException | CmdException = pymol.CmdException | |||
py_delims = { '=' : 1, '+=' : 1, '-=' : 1, '*=' : 1, | py_delims = { '=' : 1, '+=' : 1, '-=' : 1, '*=' : 1, | |||
'/=' :1, '//=' : 1, '%=' : 1, '&=' : 1, | '/=' :1, '//=' : 1, '%=' : 1, '&=' : 1, | |||
'|=' :1, '^=' : 1, '>>=' : 1,'<<=' : 1, | '|=' :1, '^=' : 1, '>>=' : 1,'<<=' : 1, | |||
'**=':1 } | '**=':1 } | |||
skipping to change at line 55 | skipping to change at line 61 | |||
def complete_sc(st,sc,type_name,postfix, mode=0): | def complete_sc(st,sc,type_name,postfix, mode=0): | |||
result = None | result = None | |||
try: | try: | |||
sc=sc() # invoke lambda functions (if any) | sc=sc() # invoke lambda functions (if any) | |||
except: | except: | |||
traceback.print_exc() | traceback.print_exc() | |||
amb = sc.interpret(st, mode) | amb = sc.interpret(st, mode) | |||
if amb==None: | if amb==None: | |||
print(" parser: no matching %s."%type_name) | colorprinting.warning(" parser: no matching %s."%type_name) | |||
elif isinstance(amb, str): | elif isinstance(amb, str): | |||
result = amb+postfix | result = amb+postfix | |||
else: | else: | |||
amb.sort() | amb.sort() | |||
print(" parser: matching %s:"%type_name) | colorprinting.suggest(" parser: matching %s:"%type_name) | |||
flist = [x for x in amb if x[0]!='_'] | flist = [x for x in amb if x[0]!='_'] | |||
lst = parsing.list_to_str_list(flist) | lst = parsing.list_to_str_list(flist) | |||
for a in lst: | for a in lst: | |||
print(a) | colorprinting.suggest(a) | |||
# now append up to point of ambiguity | # now append up to point of ambiguity | |||
if not len(flist): | if not len(flist): | |||
css = [] | css = [] | |||
else: | else: | |||
css = list(flist[0]) # common sub-string (css) | css = list(flist[0]) # common sub-string (css) | |||
for a in flist: | for a in flist: | |||
ac = list(a) | ac = list(a) | |||
tmp = css | tmp = css | |||
css = [] | css = [] | |||
for c in range(len(tmp)): | for c in range(len(tmp)): | |||
skipping to change at line 90 | skipping to change at line 96 | |||
if len(css)>len(st): | if len(css)>len(st): | |||
result = css | result = css | |||
return result | return result | |||
class NestLayer: | class NestLayer: | |||
def __init__(self): | def __init__(self): | |||
self.cont = "" | self.cont = "" | |||
self.com0 = "" | self.com0 = "" | |||
self.sc_path = "toplevel" | self.sc_path = SCRIPT_TOPLEVEL | |||
self.lineno = 0 | ||||
self.literal_python_fallback = False | ||||
self.embed_sentinel = None | self.embed_sentinel = None | |||
self.embed_dict = {} | self.embed_dict = {} | |||
self.next = [] | self.next = [] | |||
class Parser: | class Parser: | |||
def __init__(self,cmd): | def __init__(self,cmd): | |||
cmd = cmd._weakrefproxy | ||||
self.cmd = cmd | self.cmd = cmd | |||
self.nest = 0 | self.nest = 0 | |||
self.layer = { 0: NestLayer() } | self.layer = { 0: NestLayer() } | |||
self.pymol_names = self.cmd._pymol.__dict__ | self.pymol_names = self.cmd._pymol.__dict__ | |||
# parsing state implemented with dictionaries to enable safe recursi on | # parsing state implemented with dictionaries to enable safe recursi on | |||
# to arbitrary depths | # to arbitrary depths | |||
#com0 = {} # verbose line, as read in | #com0 = {} # verbose line, as read in | |||
skipping to change at line 133 | skipping to change at line 142 | |||
# The resulting value from a pymol command (if any) is stored in the | # The resulting value from a pymol command (if any) is stored in the | |||
# parser.result global variable. However, script developers will | # parser.result global variable. However, script developers will | |||
# geerally want to switch to the Python API for any of this kind of | # geerally want to switch to the Python API for any of this kind of | |||
# stuff. | # stuff. | |||
self.result = None | self.result = None | |||
# initialize parser | # initialize parser | |||
self.cmd._pymol.__script__="toplevel" | self.cmd._pymol.__script__ = SCRIPT_TOPLEVEL | |||
def exec_python(self, s, secure=False, fallback=False): | ||||
if secure: | ||||
raise SecurityException('Python expressions disallowed in this f | ||||
ile') | ||||
layer = self.layer[self.nest] | ||||
layer.literal_python_fallback = fallback | ||||
# for meaningful line number in error messages | ||||
blanklines = layer.lineno - 1 - s.count('\n') | ||||
s = '\n' * blanklines + s + '\n' | ||||
s = compile(s, layer.sc_path, 'exec') | ||||
exec(s, self.pymol_names, self.pymol_names) | ||||
# main parser routine | # main parser routine | |||
def parse(self,s,secure=0): | def parse(self,s,secure=0): | |||
layer = self.layer.get(self.nest,None) | layer = self.layer.get(self.nest,None) | |||
self.result = None | self.result = None | |||
# report any uncaught errors... | # report any uncaught errors... | |||
# WLD: this is problematic if parse is called inside an exception...removed. | # WLD: this is problematic if parse is called inside an exception...removed. | |||
# if sys.exc_info()!=(None,None,None): | # if sys.exc_info()!=(None,None,None): | |||
# traceback.print_exc() | # traceback.print_exc() | |||
# sys.exc_clear() | # sys.exc_clear() | |||
if layer.embed_sentinel!=None: | def parse_embed(): | |||
if s.strip() == layer.embed_sentinel: | if s.strip() == layer.embed_sentinel: | |||
etn = layer.embed_type | etn = layer.embed_type | |||
if etn == 0: # embedded data | if etn == 0: # embedded data | |||
print(" Embed: read %d lines."%(len(layer.embed_list))) | colorprinting.parrot(" Embed: read %d lines."%(len(layer .embed_list))) | |||
layer.embed_sentinel=None | layer.embed_sentinel=None | |||
elif etn == 1: # python block | elif etn == 1: # python block | |||
print("PyMOL>"+s.rstrip()) | colorprinting.parrot("PyMOL>"+s.rstrip()) | |||
py_block = ''.join(layer.embed_list) | py_block = ''.join(layer.embed_list) | |||
del layer.embed_list | del layer.embed_list | |||
layer.embed_sentinel=None | layer.embed_sentinel=None | |||
try: | self.exec_python(py_block) | |||
exec(py_block,self.pymol_names,self.pymol_names) | ||||
except: | ||||
traceback.print_exc() | ||||
elif etn == 2: # skip block | elif etn == 2: # skip block | |||
print(" Skip: skipped %d lines."%(layer.embed_line)) | colorprinting.parrot(" Skip: skipped %d lines."%(layer.e mbed_line)) | |||
layer.embed_sentinel=None | layer.embed_sentinel=None | |||
else: | else: | |||
etn = layer.embed_type | etn = layer.embed_type | |||
if etn == 0: # normal embedded data | if etn == 0: # normal embedded data | |||
layer.embed_list.append(s.rstrip()+"\n") | layer.embed_list.append(s.rstrip()+"\n") | |||
elif etn == 1: # python block | elif etn == 1: # python block | |||
el = layer.embed_line + 1 | el = layer.embed_line + 1 | |||
print("%5d:%s"%(el,s.rstrip())) | colorprinting.parrot("%5d:%s"%(el,s.rstrip())) | |||
layer.embed_line = el | layer.embed_line = el | |||
layer.embed_list.append(s.rstrip()+"\n") | layer.embed_list.append(s.rstrip()+"\n") | |||
elif etn == 2: | elif etn == 2: | |||
layer.embed_line = layer.embed_line + 1 | layer.embed_line = layer.embed_line + 1 | |||
return 1 | ||||
p_result = 1 | p_result = 1 | |||
layer.com0 = s | layer.com0 = s | |||
try: | try: | |||
if layer.embed_sentinel is not None: | ||||
parse_embed() | ||||
return 1 | ||||
layer.com1 = layer.com0.rstrip() # strips trailing whitespace | layer.com1 = layer.com0.rstrip() # strips trailing whitespace | |||
if len(layer.com1) > 0: | if len(layer.com1) > 0: | |||
if str(layer.com1[-1]) == "\\": | if str(layer.com1[-1]) == "\\": | |||
# prepend leftovers | # prepend leftovers | |||
if layer.cont != '': | if layer.cont != '': | |||
layer.cont = layer.cont + "\n" + layer.com1[:-1] | layer.cont = layer.cont + "\n" + layer.com1[:-1] | |||
else: | else: | |||
layer.cont = layer.com1[:-1] | layer.cont = layer.com1[:-1] | |||
else: | else: | |||
# prepend leftovers | # prepend leftovers | |||
skipping to change at line 206 | skipping to change at line 230 | |||
layer.com2 = layer.next[0] | layer.com2 = layer.next[0] | |||
layer.input = layer.com2.split(' ',1) | layer.input = layer.com2.split(' ',1) | |||
lin = len(layer.input) | lin = len(layer.input) | |||
if lin: | if lin: | |||
layer.input[0] = layer.input[0].strip() | layer.input[0] = layer.input[0].strip() | |||
com = layer.input[0] | com = layer.input[0] | |||
if (com[0:1]=='/'): | if (com[0:1]=='/'): | |||
# explicit literal python | # explicit literal python | |||
layer.com2 = layer.com2[1:].strip() | layer.com2 = layer.com2[1:].strip() | |||
if len(layer.com2)>0: | if len(layer.com2)>0: | |||
if not secure: | self.exec_python(layer.com2, secure) | |||
exec(layer.com2+"\n",self.pymol_names,se | ||||
lf.pymol_names) | ||||
else: | ||||
print('Error: Python expressions disallo | ||||
wed in this file.') | ||||
return None | ||||
elif lin>1 and layer.input[-1:][0].split(' ',1)[0] i n py_delims: | elif lin>1 and layer.input[-1:][0].split(' ',1)[0] i n py_delims: | |||
if not secure: | self.exec_python(layer.com2, secure) | |||
exec(layer.com2+"\n",self.pymol_names,self.p | ||||
ymol_names) | ||||
else: | ||||
print('Error: Python expressions disallowed | ||||
in this file.') | ||||
return None | ||||
else: | else: | |||
# try to find a keyword which matches | # try to find a keyword which matches | |||
if com in self.cmd.kwhash: | if com in self.cmd.kwhash: | |||
amb = self.cmd.kwhash.interpret(com) | amb = self.cmd.kwhash.interpret(com) | |||
if amb == None: | if amb == None: | |||
com = self.cmd.kwhash[com] | com = self.cmd.kwhash[com] | |||
elif not isinstance(amb, str): | elif not isinstance(amb, str): | |||
print('Error: ambiguous command: ') | colorprinting.warning('Error: ambiguous command: ') | |||
amb.sort() | amb.sort() | |||
amb = parsing.list_to_str_list(amb) | amb = parsing.list_to_str_list(amb) | |||
for a in amb: | for a in amb: | |||
print(a) | colorprinting.warning(a) | |||
raise QuietException | raise QuietException | |||
com = amb | com = amb | |||
if com in self.cmd.keyword: | if com in self.cmd.keyword: | |||
# here is the command and argument handling section | # here is the command and argument handling section | |||
layer.kw = self.cmd.keyword[com] | layer.kw = self.cmd.keyword[com] | |||
if layer.kw[4]>=parsing.NO_CHECK: | if layer.kw[4]>=parsing.NO_CHECK: | |||
# stricter, Python-based argument parsin g | # stricter, Python-based argument parsin g | |||
# remove line breaks (only important for Python expressions) | # remove line breaks (only important for Python expressions) | |||
layer.com2=layer.com2.replace('\n','') | layer.com2=layer.com2.replace('\n','') | |||
if layer.kw[4]>=parsing.LITERAL: # treat literally | if layer.kw[4]>=parsing.LITERAL: # treat literally | |||
layer.next = [] | layer.next = [] | |||
if not secure: | if not secure: | |||
layer.com2=layer.com1 | layer.com2=layer.com1 | |||
else: | else: | |||
print('Error: Python expressions | raise SecurityException('Python | |||
disallowed in this file. ') | expressions disallowed in this file') | |||
return 0 | ||||
if secure and (layer.kw[4]==parsing.SECU RE): | if secure and (layer.kw[4]==parsing.SECU RE): | |||
layer.next = [] | layer.next = [] | |||
print('Error: Command disallowed in | raise SecurityException('Command dis | |||
this file.') | allowed in this file') | |||
return None | ||||
else: | else: | |||
(layer.args, layer.kw_args) = \ | (layer.args, layer.kw_args) = \ | |||
parsing.prepare_call( | parsing.prepare_call( | |||
layer.kw[0], | layer.kw[0], | |||
parsing.parse_arg(layer.com2,mode=l ayer.kw[4],_self=self.cmd), | parsing.parse_arg(layer.com2,mode=l ayer.kw[4],_self=self.cmd), | |||
layer.kw[4], _self=self.cmd) # will raise exception on failure | layer.kw[4], _self=self.cmd) # will raise exception on failure | |||
self.result=layer.kw[0](*layer.args, **l ayer.kw_args) | self.result=layer.kw[0](*layer.args, **l ayer.kw_args) | |||
elif layer.kw[4]==parsing.PYTHON: | elif layer.kw[4]==parsing.PYTHON: | |||
# handle python keyword | # handle python keyword | |||
layer.com2 = layer.com2.strip() | layer.com2 = layer.com2.strip() | |||
if len(layer.com2)>0: | if len(layer.com2)>0: | |||
if not secure: | self.exec_python(layer.com2, sec | |||
exec(layer.com2+"\n",self.py | ure) | |||
mol_names,self.pymol_names) | ||||
else: | ||||
layer.next = [] | ||||
print('Error: Python express | ||||
ions disallowed in this file.') | ||||
return None | ||||
else: | else: | |||
# remove line breaks (only important for Python expressions) | # remove line breaks (only important for Python expressions) | |||
layer.com2=layer.com2.replace('\n','') | layer.com2=layer.com2.replace('\n','') | |||
# old parsing style, being phased out | # old parsing style, being phased out | |||
if layer.kw[4]==parsing.ABORT: | if layer.kw[4]==parsing.ABORT: | |||
return None # SCRIPT ABORT EXIT POIN T | return None # SCRIPT ABORT EXIT POIN T | |||
if layer.kw[4]==parsing.MOVIE: # copy li teral single line, no breaks | if layer.kw[4]==parsing.MOVIE: # copy li teral single line, no breaks | |||
layer.next = [] | layer.next = [] | |||
if not secure: | if not secure: | |||
layer.input = layer.com1.split(' ',1) | layer.input = layer.com1.split(' ',1) | |||
else: | else: | |||
print('Error: Movie commands dis | raise SecurityException('Movie c | |||
allowed in this file. ') | ommands disallowed in this file') | |||
return None | ||||
if len(layer.input)>1: | if len(layer.input)>1: | |||
layer.args = parsing.split(layer.inp ut[1],layer.kw[3]) | layer.args = parsing.split(layer.inp ut[1],layer.kw[3]) | |||
while 1: | while 1: | |||
nArg = len(layer.args) - 1 | nArg = len(layer.args) - 1 | |||
c = 0 | c = 0 | |||
while c < nArg: | while c < nArg: | |||
if ( layer.args[c].count('(' )!= | if ( layer.args[c].count('(' )!= | |||
layer.args[c].count(')' )): | layer.args[c].count(')' )): | |||
tmp=layer.args[c+1] | tmp=layer.args[c+1] | |||
layer.args.remove(tmp) | layer.args.remove(tmp) | |||
skipping to change at line 316 | skipping to change at line 324 | |||
# | # | |||
self.result=layer.kw[0](*layer.a rgs) | self.result=layer.kw[0](*layer.a rgs) | |||
# | # | |||
elif (layer.kw[4]==parsing.EMBED): | elif (layer.kw[4]==parsing.EMBED): | |||
layer.next = [] | layer.next = [] | |||
if secure or self.nest==0: # onl y legal on top level and p1m files | if secure or self.nest==0: # onl y legal on top level and p1m files | |||
l = len(layer.args) | l = len(layer.args) | |||
if l>0: | if l>0: | |||
key = layer.args[0] | key = layer.args[0] | |||
else: | else: | |||
key = os.path.splitext(o s.path.basename(layer.sc_path))[0] | key = self.get_default_k ey() | |||
if l>1: | if l>1: | |||
format = layer.args[1] | format = layer.args[1] | |||
else: | else: | |||
format = 'pdb' | format = 'pdb' | |||
if l>2: | if l>2: | |||
layer.embed_sentinel = l ayer.args[2] | layer.embed_sentinel = l ayer.args[2] | |||
else: | else: | |||
layer.embed_sentinel = " embed end" | layer.embed_sentinel = " embed end" | |||
list = [] | list = [] | |||
layer.embed_dict[key] = ( fo rmat, list ) | layer.embed_dict[key] = ( fo rmat, list ) | |||
skipping to change at line 382 | skipping to change at line 390 | |||
elif len(layer.input[0]): | elif len(layer.input[0]): | |||
if layer.input[0][0]=='@': | if layer.input[0][0]=='@': | |||
path = exp_path(layer.com2[1:].strip()) | path = exp_path(layer.com2[1:].strip()) | |||
if path[-3:].lower()=='p1m': | if path[-3:].lower()=='p1m': | |||
nest_securely = 1 | nest_securely = 1 | |||
else: | else: | |||
nest_securely = secure | nest_securely = secure | |||
if re.search("\.py$|\.pym$",path) != Non e: | if re.search("\.py$|\.pym$",path) != Non e: | |||
if self.cmd._feedback(fb_module.pars er,fb_mask.warnings): | if self.cmd._feedback(fb_module.pars er,fb_mask.warnings): | |||
print("Warning: use 'run' instea d of '@' with Python files?") | print("Warning: use 'run' instea d of '@' with Python files?") | |||
layer.script = open(path,'r') | layer.script = open(path,'rU') | |||
self.cmd._pymol.__script__ = path | self.cmd._pymol.__script__ = path | |||
self.nest=self.nest+1 | self.nest=self.nest+1 | |||
self.layer[self.nest] = NestLayer() | self.layer[self.nest] = NestLayer() | |||
layer = self.layer[self.nest] | layer = self.layer[self.nest] | |||
layer.cont='' | layer.cont='' | |||
layer.sc_path=path | layer.sc_path=path | |||
layer.embed_sentinel=None | layer.embed_sentinel=None | |||
while 1: | while 1: | |||
layer.com0 = self.layer[self.nest-1 ].script.readline() | layer.com0 = self.layer[self.nest-1 ].script.readline() | |||
self.layer[self.nest].lineno += 1 | ||||
if not layer.com0: break | if not layer.com0: break | |||
inp_cmd = layer.com0 | inp_cmd = layer.com0 | |||
tmp_cmd = inp_cmd.strip() | tmp_cmd = inp_cmd.strip() | |||
if len(tmp_cmd): | if len(tmp_cmd): | |||
if tmp_cmd[0] not in ['#','_','/ ']: # suppress comments, internals, python | if tmp_cmd[0] not in ['#','_','/ ']: # suppress comments, internals, python | |||
if layer.embed_sentinel==Non e: | if layer.embed_sentinel==Non e: | |||
print("PyMOL>"+tmp_cmd) | colorprinting.parrot("Py MOL>"+tmp_cmd) | |||
elif tmp_cmd[0]=='_' and \ | elif tmp_cmd[0]=='_' and \ | |||
tmp_cmd[1:2] in [' ','']: # "_ " remove echo suppression signal | tmp_cmd[1:2] in [' ','']: # "_ " remove echo suppression signal | |||
inp_cmd=inp_cmd[2:] | inp_cmd=inp_cmd[2:] | |||
pp_result = self.parse(inp_cmd,nest_ securely) | pp_result = self.parse(inp_cmd,nest_ securely) | |||
if pp_result==None: # RECURSION | if pp_result==None: # RECURSION | |||
break # abort command gets us ou t | break # abort command gets us ou t | |||
elif pp_result==0: # QuietException | elif pp_result==0: # QuietException | |||
if self.cmd.get_setting_boolean( "stop_on_exceptions"): | if self.cmd.get_setting_boolean( "stop_on_exceptions"): | |||
p_result = 0 # signal an err or occurred | p_result = 0 # signal an err or occurred | |||
print("PyMOL: stopped on exc eption.") | colorprinting.error("PyMOL: stopped on exception.") | |||
break; | break; | |||
self.nest=self.nest-1 | self.nest=self.nest-1 | |||
layer=self.layer[self.nest] | layer=self.layer[self.nest] | |||
layer.script.close() | layer.script.close() | |||
self.cmd.__script__ = layer.sc_path | self.cmd._pymol.__script__ = layer.sc_pa th | |||
else: # nothing found, try literal python | else: # nothing found, try literal python | |||
layer.com2 = layer.com2.strip() | layer.com2 = layer.com2.strip() | |||
if len(layer.com2)>0: | if len(layer.com2)>0: | |||
if not secure: | if not secure: | |||
exec(layer.com2+"\n",self.pymol_ names,self.pymol_names) | self.exec_python(layer.com2, fal lback=True) | |||
elif layer.input[0][0:1]!='#': | elif layer.input[0][0:1]!='#': | |||
print('Error: unrecognized keywo rd: '+layer.input[0]) | colorprinting.error('Error: unre cognized keyword: '+layer.input[0]) | |||
if (len(layer.next)>1) and p_result: | if (len(layer.next)>1) and p_result: | |||
# continue parsing if no error or break has occurred | # continue parsing if no error or break has occurred | |||
self.nest=self.nest+1 | self.nest=self.nest+1 | |||
self.layer[self.nest] = NestLayer() | self.layer[self.nest] = NestLayer() | |||
layer=self.layer[self.nest] | layer=self.layer[self.nest] | |||
layer.com0 = self.layer[self.nest-1].next[1] | layer.com0 = self.layer[self.nest-1].next[1] | |||
self.layer[self.nest-1].next=[] | self.layer[self.nest-1].next=[] | |||
layer.cont='' | layer.cont='' | |||
layer.embed_sentinel=None | layer.embed_sentinel=None | |||
p_result = self.parse(layer.com0,secure) # RECURSION | p_result = self.parse(layer.com0,secure) # RECURSION | |||
self.nest=self.nest-1 | self.nest=self.nest-1 | |||
layer=self.layer[self.nest] | layer=self.layer[self.nest] | |||
except QuietException: | except (QuietException, CmdException) as e: | |||
if self.cmd._feedback(fb_module.parser,fb_mask.blather): | if e.args: | |||
print("Parser: QuietException caught") | colorprinting.error(e) | |||
p_result = 0 # notify caller that an error was encountered | ||||
except CmdException as e: | ||||
if e.message: | ||||
print(e) | ||||
if self.cmd._feedback(fb_module.parser,fb_mask.blather): | if self.cmd._feedback(fb_module.parser,fb_mask.blather): | |||
print("Parser: CmdException caught.") | print("Parser: caught " + type(e).__name__) | |||
p_result = 0 | p_result = 0 | |||
except SecurityException as e: | ||||
colorprinting.error('Error: %s' % (e,)) | ||||
p_result = None | ||||
except: | except: | |||
traceback.print_exc() | exc_type, exc_value, tb = colorprinting.print_exc( | |||
if self.cmd._feedback(fb_module.parser,fb_mask.blather): | [__file__, SCRIPT_TOPLEVEL]) | |||
print("PyMOL: Caught an unknown exception.") | ||||
p_result = 0 # notify caller that an error was encountered | p_result = 0 # notify caller that an error was encountered | |||
if not p_result and self.cmd._pymol.invocation.options.exit_on_error : | if not p_result and self.cmd._pymol.invocation.options.exit_on_error : | |||
self.cmd.quit(1) | self.cmd.quit(1) | |||
return p_result # 0 = Exception, None = abort, 1 = ok | return p_result # 0 = Exception, None = abort, 1 = ok | |||
def get_embedded(self,key=None): | def get_embedded(self,key=None): | |||
layer = self.layer[self.nest] | layer = self.layer[self.nest] | |||
dict = layer.embed_dict | dict = layer.embed_dict | |||
if key==None: | if key==None: | |||
key = self.get_default_key() | key = self.get_default_key() | |||
skipping to change at line 526 | skipping to change at line 534 | |||
pre = re.sub("[^ ]*$","",pre,count=1) # trim 1 arg | pre = re.sub("[^ ]*$","",pre,count=1) # trim 1 arg | |||
pre = re.sub(r"^ *",'',pre) | pre = re.sub(r"^ *",'',pre) | |||
pre = full+' '+pre | pre = full+' '+pre | |||
pat = re.sub(r".*[\, ]",'',st) | pat = re.sub(r".*[\, ]",'',st) | |||
# print ":"+pre+":"+pat+":" | # print ":"+pre+":"+pat+":" | |||
# print tuple([pat] + self.cmd.auto_arg[count][fu ll]) | # print tuple([pat] + self.cmd.auto_arg[count][fu ll]) | |||
result = complete_sc(*tuple([pat] + self.cmd.aut o_arg[count][full]), **{}) | result = complete_sc(*tuple([pat] + self.cmd.aut o_arg[count][full]), **{}) | |||
except: | except: | |||
traceback.print_exc() | traceback.print_exc() | |||
if not flag: # otherwise fallback onto filename completion | if not flag: # otherwise fallback onto filename completion | |||
st = self.cmd.as_pathstr(st) | ||||
loc = 1 + max(map(st.rfind, ',@')) | loc = 1 + max(map(st.rfind, ',@')) | |||
if not loc: | if not loc: | |||
loc = 1 + st.find(' ') | loc = 1 + st.find(' ') | |||
pre = st[:loc] | pre = st[:loc] | |||
st3 = st[loc:].lstrip() | st3 = st[loc:].lstrip() | |||
flist = glob.glob(exp_path(st3)+"*") | flist = glob.glob(exp_path(st3)+"*") | |||
# environment variable completion | ||||
if not flist and st3.startswith('$'): | ||||
flist = ['$' + var for var in os.environ | ||||
if var.startswith(st3[1:])] | ||||
lf = len(flist) | lf = len(flist) | |||
if lf == 0: | if lf == 0: | |||
print(" parser: no matching files.") | print(" parser: no matching files.") | |||
elif lf==1: | elif lf==1: | |||
result = flist[0] | result = flist[0] | |||
if os.path.isdir(flist[0]): | if os.path.isdir(flist[0]): | |||
result += '/' # do not use os.path.sep here | result += '/' # do not use os.path.sep here | |||
else: | else: | |||
flist.sort() | flist.sort() | |||
print(" parser: matching files:") | print(" parser: matching files:") | |||
End of changes. 38 change blocks. | ||||
66 lines changed or deleted | 77 lines changed or added |