Skip to content

Commit 018337e

Browse files
author
ocaisa
authored
Merge pull request #3333 from boegel/sanity_LD_LIBRARY_PATH
avoid empty entries in $LD_LIBRARY_PATH and other path-like environment variables
2 parents a8d397d + 772d823 commit 018337e

File tree

2 files changed

+61
-9
lines changed

2 files changed

+61
-9
lines changed

easybuild/tools/environment.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,18 +189,39 @@ def sanitize_env():
189189
"""
190190
Sanitize environment.
191191
192-
This function undefines all $PYTHON* environment variables,
193-
since they may affect the build/install procedure of Python packages.
192+
This function:
194193
195-
cfr. https://docs.python.org/2/using/cmdline.html#environment-variables
194+
* Filters out empty entries from environment variables like $PATH, $LD_LIBRARY_PATH, etc.
195+
Empty entries make no sense, and can cause problems,
196+
see for example https://github.com/easybuilders/easybuild-easyconfigs/issues/9843 .
196197
197-
While the $PYTHON* environment variables may be relevant/required for EasyBuild itself,
198-
and for any non-stdlib Python packages it uses,
199-
they are irrelevant (and potentially harmful) when installing Python packages.
198+
* Undefines all $PYTHON* environment variables,
199+
since they may affect the build/install procedure of Python packages.
200200
201-
Note that this is not an airtight protection against the Python being used in the build/install procedure
202-
picking up non-stdlib Python packages (e.g., setuptools, vsc-base, ...), thanks to the magic of .pth files,
203-
cfr. https://docs.python.org/2/library/site.html .
201+
cfr. https://docs.python.org/2/using/cmdline.html#environment-variables
202+
203+
While the $PYTHON* environment variables may be relevant/required for EasyBuild itself,
204+
and for any non-stdlib Python packages it uses,
205+
they are irrelevant (and potentially harmful) when installing Python packages.
206+
207+
Note that this is not an airtight protection against the Python being used in the build/install procedure
208+
picking up non-stdlib Python packages (e.g., setuptools, vsc-base, ...), thanks to the magic of .pth files,
209+
cfr. https://docs.python.org/2/library/site.html .
204210
"""
211+
212+
# remove empty entries from $*PATH variables
213+
for key in ['CPATH', 'LD_LIBRARY_PATH', 'LIBRARY_PATH', 'LD_PRELOAD', 'PATH']:
214+
val = os.getenv(key)
215+
if val:
216+
entries = val.split(os.pathsep)
217+
if '' in entries:
218+
_log.info("Found %d empty entries in $%s, filtering them out...", entries.count(''), key)
219+
newval = os.pathsep.join(x for x in entries if x)
220+
if newval:
221+
setvar(key, newval)
222+
else:
223+
unset_env_vars([key], verbose=False)
224+
225+
# unset all $PYTHON* environment variables
205226
keys_to_unset = [key for key in os.environ if key.startswith('PYTHON')]
206227
unset_env_vars(keys_to_unset, verbose=False)

test/framework/environment.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,37 @@ def test_unset_env_vars(self):
131131
}
132132
self.assertEqual(res, expected)
133133

134+
def test_sanitize_env(self):
135+
"""Test sanitize_env function."""
136+
137+
# define $*PATH variable that include empty entries, those should get filtered out
138+
os.environ['PATH'] = '/bar::/foo:' + self.test_prefix # middle empty entry
139+
os.environ['LD_LIBRARY_PATH'] = '/apps/slurm/default/lib:/usr/lib:' # trailing empty entry
140+
os.environ['LIBRARY_PATH'] = self.test_prefix + ':' + os.environ['HOME'] # no empty entries here
141+
os.environ['CPATH'] = ':' + self.test_prefix # leading empty entry
142+
os.environ['LD_PRELOAD'] = ':::' # only empty entries (should get unset!)
143+
144+
# define $PYTHON* environment variables, these should be unset by sanitize_env
145+
os.environ['PYTHONNOUSERSITE'] = '1'
146+
os.environ['PYTHONPATH'] = self.test_prefix
147+
os.environ['PYTHONOPTIMIZE'] = '1'
148+
149+
env.sanitize_env()
150+
151+
self.assertFalse(any(x for x in os.environ.keys() if x.startswith('PYTHON')))
152+
153+
expected = {
154+
'CPATH': self.test_prefix,
155+
'LD_LIBRARY_PATH': '/apps/slurm/default/lib:/usr/lib',
156+
'LIBRARY_PATH': self.test_prefix + ':' + os.environ['HOME'],
157+
'PATH': '/bar:/foo:' + self.test_prefix,
158+
}
159+
for key in sorted(expected):
160+
self.assertEqual(os.getenv(key), expected[key])
161+
self.assertEqual(os.environ[key], expected[key])
162+
163+
self.assertEqual(os.getenv('LD_PRELOAD'), None)
164+
134165

135166
def suite():
136167
""" returns all the testcases in this module """

0 commit comments

Comments
 (0)