brightway-lca / bw_recipe_2016

ReCiPe 2016 LCIA method for Brightway
BSD 3-Clause "New" or "Revised" License
4 stars 4 forks source link

TypeError during run #10

Closed marc-vdm closed 1 year ago

marc-vdm commented 2 years ago

Hi there,

I just tried add these categories to my AB environment and it failed. I installed the lib through pip (in AB environment), ran python in a miniconda terminal, imported and excecuted the add_recipe_2016() function and got this error:

>>> from bw_recipe_2016 import add_recipe_2016
>>> add_recipe_2016()
Adding StratosphericOzoneDepletion
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\*\miniconda3\envs\ab\lib\site-packages\bw_recipe_2016\__init__.py", line 112, in add_recipe_2016
    category.apply_strategies(verbose=False)
  File "C:\Users\*\miniconda3\envs\ab\lib\site-packages\bw2io\importers\base.py", line 69, in apply_strategies
    self.apply_strategy(func, verbose)
  File "C:\Users\*\miniconda3\envs\ab\lib\site-packages\bw2io\importers\base.py", line 48, in apply_strategy
    self.data = strategy(self.data)
  File "C:\Users\*\miniconda3\envs\ab\lib\site-packages\bw_recipe_2016\strategies\string_manipulation.py", line 31, in split_synonyms
    match = multiple.match(cf["synonyms"])
TypeError: expected string or bytes-like object

Any thoughts on how to resolve this, or what I could be doing wrong?

Cheers, M

ChristinaKockel commented 2 years ago

I had the same problem and fixed it with the following small changes to the module scripts (in the module folder, with the given path in the error code):

For the file strategies/string_manipulation.py the function split_synonyms:

def split_synonyms(data): """Split synonyms given in one string. Also makes sure synonyms exists, has no trailing whitespace, and is a list.

E.g. ``dinitrogen oxide (nitrous oxide)`` to ``["dinitrogen oxide", "nitrous oxide"]``,"""
for ds in data:
    for cf in ds["exchanges"]:
        if "synonyms" in cf:
            if cf['synonyms'] is None:
                cf["synonyms"] = []
            else: 
                match = multiple.match(cf["synonyms"])
                if match:
                    cf["synonyms"] = [x.strip() for x in match.groups()]
                elif not isinstance(cf["synonyms"], list):
                    cf["synonyms"] = [cf["synonyms"].strip()]
        else:
            cf["synonyms"] = []
return data

And for the file strategies/matching.py the function category_match:

def category_match(a, b): """Return bool, whether the starting categories in a match the categories in b.

For example, ``category_match({'categories': ('foo',)}, {"categories": ('foo', 'bar')})`` is true."""
if b["categories"] is not None: 
    return tuple(a["categories"][: len(b["categories"])]) == tuple(b["categories"])
else:
    return tuple(a["categories"])

This should only fix a formal error where the code 'None' is handled incorrectly and content wise everything should remain the same. I tested it with the Midpoint and Hierarchist categories of the method and it worked fine. Maybe one of the developer could check this :)

I hope this helps you too!

Best, Christina

marc-vdm commented 2 years ago

That worked, thanks! I've made a Pull Request with your fix for the project.