Skip to content

Commit 7cbccfe

Browse files
committed
Use pickle instead of repr/ast.literal_eval
This fixes a crash with objects like`SpecifierSet`
1 parent ebaa914 commit 7cbccfe

1 file changed

Lines changed: 11 additions & 9 deletions

File tree

colcon_python_setup_py/package_identification/python_setup_py.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Copyright 2016-2018 Dirk Thomas
22
# Licensed under the Apache License, Version 2.0
33

4-
import ast
54
import distutils.core
65
import os
6+
import pickle
77
from pathlib import Path
88
import runpy
99
try:
@@ -134,11 +134,11 @@ def get_setup_arguments(setup_py):
134134
setuptools.setup = setuptools_setup
135135
except NameError:
136136
pass
137-
# filter out any data which doesn't work with ast.literal_eval
137+
# filter out any data which doesn't serialize
138138
for key, value in list(data.items()):
139139
try:
140-
ast.literal_eval(repr(value))
141-
except SyntaxError:
140+
pickle.dumps(value)
141+
except pickle.PicklingError:
142142
del data[key]
143143
return data
144144

@@ -237,9 +237,9 @@ def get_setup_arguments_with_context(setup_py, env):
237237
cmd = [sys.executable, '-c', ';'.join(code_lines)]
238238
result = subprocess.run(
239239
cmd, stdout=subprocess.PIPE, env=env, check=True)
240-
output = result.stdout.decode('utf-8')
240+
output = result.stdout
241241

242-
return ast.literal_eval(output)
242+
return pickle.loads(output)
243243

244244

245245
_setup_information_cache = {}
@@ -269,6 +269,7 @@ def get_setup_information(setup_py, *, env=None):
269269
def _get_setup_information(setup_py, *, env=None):
270270
code_lines = [
271271
'import sys',
272+
'import pickle',
272273
'from distutils.core import run_setup',
273274

274275
'dist = run_setup('
@@ -293,14 +294,15 @@ def _get_setup_information(setup_py, *, env=None):
293294
# skip values with custom type OrderedSet
294295
" if k not in ('license_files', 'provides_extras')}",
295296

296-
"sys.stdout.buffer.write(repr(data).encode('utf-8'))"]
297+
"pickle.dump(data, sys.stdout)"]
298+
297299

298300
# invoke distutils.core.run_setup() in a separate interpreter
299301
cmd = [
300302
sys.executable, '-c', ';'.join(line.lstrip() for line in code_lines)]
301303
result = subprocess.run(
302304
cmd, stdout=subprocess.PIPE,
303305
cwd=os.path.abspath(str(setup_py.parent)), check=True, env=env)
304-
output = result.stdout.decode('utf-8')
306+
output = result.stdout
305307

306-
return ast.literal_eval(output)
308+
return pickle.loads(output)

0 commit comments

Comments
 (0)