gnuradio / pybombs

PyBOMBS (Python Build Overlay Managed Bundle System) is the GNU Radio install management system for resolving dependencies and pulling in out-of-tree projects.
https://gnuradio.org
GNU General Public License v3.0
414 stars 189 forks source link

Incompatible ruamel.yaml 0.16.5 with pybombs 2.3.3 #559

Open SaikWolf opened 4 years ago

SaikWolf commented 4 years ago

I've been getting failures with pybombs 2.3.3 and ruamel.yaml 0.16.5

$ pybombs Traceback (most recent call last):   File "/usr/local/lib/python3.5/dist-packages/pybombs/config_file.py", line 110, in init     self.data = OrderedDict(self.yaml.load(fn.read()) or {}) TypeError: unhashable type: 'CommentedSeq'

Config file:

!!python/object/apply:collections.OrderedDict
- - - config
    - default_prefix: sandbox
      elevate_pre_args:
      - sudo
      - -H
      git-cache: /home/user/.pybombs/gitcache
      makewidth: 12
      packagers: apt,pymod,pkgconfig,cmd,pip
  - - prefix_aliases
    - sandbox: /home/user/workspace/sandbox
      working: /home/user/workspace/working

With the following hack, was able to get back to functional, but haven't been able to put anymore testing into it.

pybombs/config_file.py -> AbstractYaml -> def load(self,fd)

    def load(self, fd):
        """Load contents of a file descriptor and return a dictionary."""
        if yaml.version_info[0] >= 0 and yaml.version_info[1] >= 16 and yaml.version_info[2] >= 5:
            yl = self._load(fd)
            def sanitize(data):
                def strip(cs):
                    if isinstance(cs,yaml.comments.CommentedSeq):
                        cs = cs.copy()
                    if isinstance(cs,yaml.comments.CommentedMap):
                        cs = OrderedDict(cs)
                    if isinstance(cs,list):
                        for idx in range(len(cs)):
                            cs[idx] = strip(cs[idx])
                    if isinstance(cs,OrderedDict):
                        keys = list(cs.keys())
                        for k in keys:
                            cs[k] = strip(cs[k])
                    return cs
                sanitized = strip(data)
                if isinstance(data,yaml.comments.CommentedSeq):
                    for idx in range(len(sanitized)):
                        for ind in range(len(sanitized[idx])):
                            sanitized[idx][ind] = tuple(sanitized[idx][ind])
                        sanitized[idx] = OrderedDict(sanitized[idx])
                    if len(sanitized) == 1:
                        sanitized = sanitized[0]
                return sanitized
            return sanitize(yl)
        else:
            return self._load(fd)