Fix a regression in 3.45.0 that broke parsing of old-style .py config files

unicode_literals means we now have to mark bytestrings explicitly before
trying to exec the source
This commit is contained in:
Kovid Goyal 2019-07-14 15:24:01 +05:30
parent 312332a847
commit cb14986b8d
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -19,6 +19,26 @@ from polyglot.builtins import unicode_type, iteritems, map
plugin_dir = os.path.join(config_dir, 'plugins') plugin_dir = os.path.join(config_dir, 'plugins')
def parse_old_style(src):
if ispy3:
import pickle as cPickle
else:
import cPickle
options = {'cPickle':cPickle}
try:
if not isinstance(src, unicode_type):
src = src.decode('utf-8')
src = src.replace('PyQt%d.QtCore' % 4, 'PyQt5.QtCore')
src = re.sub(r'cPickle\.loads\(([\'"])', r'cPickle.loads(b\1', src)
exec(src, options)
except Exception as err:
try:
print('Failed to parse old style options string with error: {}'.format(err))
except Exception:
pass
return options
def to_json(obj): def to_json(obj):
import datetime import datetime
if isinstance(obj, bytearray): if isinstance(obj, bytearray):
@ -156,6 +176,7 @@ class OptionSet(object):
self.group_list = [] self.group_list = []
self.groups = {} self.groups = {}
self.set_buffer = {} self.set_buffer = {}
self.loads_pat = None
def has_option(self, name_or_option_object): def has_option(self, name_or_option_object):
if name_or_option_object in self.preferences: if name_or_option_object in self.preferences:
@ -276,30 +297,12 @@ class OptionSet(object):
return match.group() return match.group()
return '' return ''
def parse_old_style(self, src):
if ispy3:
import pickle as cPickle
else:
import cPickle
options = {'cPickle':cPickle}
try:
if not isinstance(src, unicode_type):
src = src.decode('utf-8')
src = src.replace('PyQt%d.QtCore' % 4, 'PyQt5.QtCore')
exec(src, options)
except Exception as err:
try:
print('Failed to parse old style options string with error: {}'.format(err))
except Exception:
pass
return options
def parse_string(self, src): def parse_string(self, src):
options = {} options = {}
if src: if src:
is_old_style = (isinstance(src, bytes) and src.startswith(b'#')) or (isinstance(src, unicode_type) and src.startswith(u'#')) is_old_style = (isinstance(src, bytes) and src.startswith(b'#')) or (isinstance(src, unicode_type) and src.startswith(u'#'))
if is_old_style: if is_old_style:
options = self.parse_old_style(src) options = parse_old_style(src)
else: else:
try: try:
options = json_loads(src) options = json_loads(src)