Skip to content

Commit

Permalink
Merge pull request #202 from desihub/remove_dependencies
Browse files Browse the repository at this point in the history
add support for removing dependencies
  • Loading branch information
sbailey committed Sep 23, 2023
2 parents 3037a6f + 0bd555b commit f9bd0ae
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 12 deletions.
71 changes: 61 additions & 10 deletions py/desiutil/depend.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,11 @@ def getdep(header, name):
for i in range(100):
namekey = 'DEPNAM{:02d}'.format(i)
verkey = 'DEPVER{:02d}'.format(i)
if namekey in header:
if header[namekey] == name:
return header[verkey]
elif i == 0:
continue # ok if DEPNAM00 is missing; continue to DEPNAME01
else:
raise KeyError('{} version not found'.format(name))
if namekey in header and header[namekey] == name:
return header[verkey]

# if we exited the loop, the name wasn't found in any DEPNAMnn
raise KeyError('{} version not found'.format(name))


def hasdep(header, name):
Expand Down Expand Up @@ -173,12 +171,11 @@ def iterdep(header):
for i in range(100):
namekey = 'DEPNAM{:02d}'.format(i)
verkey = 'DEPVER{:02d}'.format(i)
if namekey not in header and i == 0:
continue
if namekey in header:
yield (header[namekey], header[verkey])
else:
return
continue # ok if some DEPNAMnn are missing

return


Expand Down Expand Up @@ -229,6 +226,37 @@ def mergedep(srchdr, dsthdr, conflict='src'):
setdep(dsthdr, name, version)


def removedep(header, name):
"""
Removed dependency ``name`` from ``header``.
Parameters
----------
header : dict-like
header object with DEPNAMnn/DEPVERnn keywords
name : str
name of dependency to remove
Notes
-----
Modifies header in-place
Raises
------
ValueError
If ``name`` is not present in any of the DEPNAMnn keys
"""
for i in range(100):
namekey = 'DEPNAM{:02d}'.format(i)
verkey = 'DEPVER{:02d}'.format(i)
if (namekey in header) and (header[namekey] == name):
del header[namekey]
del header[verkey]
break
else:
raise ValueError(f'{name} not found in header DEPNAMnn keywords')


def add_dependencies(header, module_names=None, long_python=False,
envvar_names=None):
'''Adds ``DEPNAMnn``, ``DEPVERnn`` keywords to header for imported modules.
Expand Down Expand Up @@ -289,6 +317,29 @@ def add_dependencies(header, module_names=None, long_python=False,
setdep(header, envvar, 'NOT_SET')


def remove_dependencies(header):
"""
Remove all DEPNAMnn/DEPVERnn dependencies from a header
Parameters
----------
header : dict-like
header with DEPNAMnn/DEPVERnn keywords to remove
Notes
-----
Updates header in-place
"""
# Assemble version keys first to avoid removing while iterating
keys = list()
for name, version in iterdep(header):
keys.append(name)

# now remove all keys
for name in keys:
removedep(header, name)


class Dependencies(object):
"""Dictionary-like object to track dependencies.
Expand Down
45 changes: 43 additions & 2 deletions py/desiutil/test/test_depend.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import sys
import os
from collections import OrderedDict
from ..depend import (setdep, getdep, hasdep, iterdep, mergedep, Dependencies,
add_dependencies)
from ..depend import (setdep, getdep, hasdep, iterdep, mergedep, removedep,
Dependencies, add_dependencies, remove_dependencies)
from .. import __version__ as desiutil_version

try:
Expand Down Expand Up @@ -281,3 +281,44 @@ def test_add_dependencies(self):
hdr = OrderedDict()
add_dependencies(hdr)
self.assertTrue(getdep(hdr, 'DESI_ROOT'), 'NOT_SET')

def test_remove_dependencies(self):
"""test removedep and remove_dependencies"""

# add and remove a single dependency
hdr = dict(HELLO='not a DEPNAMnn/DEPVERnn keyword')
setdep(hdr, 'blat', 'foo')
self.assertTrue(hasdep(hdr, 'blat'))
self.assertTrue('HELLO' in hdr)
removedep(hdr, 'blat')
self.assertFalse(hasdep(hdr, 'blat'))
self.assertTrue('HELLO' in hdr)

# remove a single dependency in the middle while preserving others
setdep(hdr, 'blat', 'foo')
setdep(hdr, 'biz', 'bat')
setdep(hdr, 'kum', 'quat')
removedep(hdr, 'biz')
self.assertTrue(hasdep(hdr, 'blat'))
self.assertFalse(hasdep(hdr, 'biz'))
self.assertTrue(hasdep(hdr, 'kum'))
self.assertTrue('HELLO' in hdr)

# Add another dependency doesn't trip on the one that was removed
setdep(hdr, 'abc', 'xyz')
self.assertTrue(hasdep(hdr, 'blat'))
self.assertTrue(hasdep(hdr, 'kum'))
self.assertTrue(hasdep(hdr, 'abc'))
self.assertTrue('HELLO' in hdr)

# remove all dependencies
remove_dependencies(hdr)
self.assertFalse(hasdep(hdr, 'blat'))
self.assertFalse(hasdep(hdr, 'biz'))
self.assertFalse(hasdep(hdr, 'kum'))
self.assertTrue('HELLO' in hdr)
for key in hdr:
self.assertFalse(key.startswith('DEP'))

with self.assertRaises(ValueError):
removedep(hdr, 'not_there')

0 comments on commit f9bd0ae

Please sign in to comment.