loot / libloot-python

A Python module that wraps libloot.
GNU General Public License v3.0
6 stars 1 forks source link

loot-api-python v2.0.0 throws RuntimeError: bad cast #9

Closed D4id4los closed 6 years ago

D4id4los commented 6 years ago

Greetings @WrinklyNinja, I am trying to update Wrye Bash to use the new loot-api v2.0.0 but I keep getting those runtime errors when calling any method of DatabaseInterface. A minimum working example is:

from loot_api import GameType
from loot_api import create_database

masterlist_path = u'C:\\Users\\daidalos\\AppData\\Local\\LOOT\\Oblivion\\masterlist.yaml'
game_path = u'D:\\games\\Oblivion'

db = create_database(GameType.tes4, game_path)

db.load_lists(masterlist_path)
tags = db.get_plugin_tags(u'Unofficial Oblivion Patch.esp')

the resulting output is:

E:\software\Python27\python.exe E:/wrye_bash/main_repo/wrye-bash/scripts/test_loot_api.py [2017-09-28 22:43:28.060461] [0x000027c0] [info] Initialising load order data for game of type 0 at: > "D:\games\Oblivion" [2017-09-28 22:43:28.061461] [0x000027c0] [debug] Loading file: "C:\Users\daidalos\AppData\Local\LOOT\Oblivion\masterlist.yaml" [2017-09-28 22:43:28.260473] [0x000027c0] [trace] Testing condition syntax: active("Oblivion.esm") and active("Nehrim.esm") [2017-09-28 22:43:28.260473] [0x000027c0] [trace] Checking to see if the path ""Oblivion.esm"" is safe. [2017-09-28 22:43:28.260473] [0x000027c0] [trace] Active check result: false [2017-09-28 22:43:28.260473] [0x000027c0] [trace] Checking to see if the path ""Nehrim.esm"" is safe. [2017-09-28 22:43:28.260473] [0x000027c0] [trace] Active check result: false Traceback (most recent call last): File "E:/wrye_bash/main_repo/wrye-bash/scripts/test_loot_api.py", line 15, in db.load_lists(masterlist_path) RuntimeError: bad cast

Do you have any idea what could cause this?

Ortham commented 6 years ago

Nope, I'll have to investigate.

Ortham commented 6 years ago

I'm not going to look at this until the LOOT API has been updated with ESL support, as that will involve a potentially-relevant API change, and one thing at a time.

Ortham commented 6 years ago

I couldn't replicate this, I suspect it's something to do with your environment, maybe LOOT is throwing an exception that's getting mapped incorrectly to a Python exception...

What plugins do you have installed, and what's your masterlist version too?

I've also just pushed an update to the latest LOOT API build, can you check if this build works? It has breaking changes (so the next release will be v3.0.0), but they're minor, just make sure to pass True as a second parameter now when getting plugin tags and cleanliness.

D4id4los commented 6 years ago

Hmm, thanks for looking into it. I can't get it to work with v2 or v3. I'll post at the wrye bash issue to see if some other guy can replicate it or if it's really just something with my environment messing things up.

D4id4los commented 6 years ago

Utumno tied it out as well (the new v3.0.0) and had the same issue. I created the following zip file to test this: loot_api_v3_test.zip Both of us get a RuntimeError: bad cast on line 11 db.load_lists(masterlist_path). I'm not quite sure what else I should try out. I tried building loot-api yesterday to better test it, but could not get it to run.

The masterlist is the latest oblivion masterlist taken from github.

Ortham commented 6 years ago

Ah, you're not calling loot_api.initialise_locale("") before everything else.

D4id4los commented 6 years ago

That fixes it. Thank you.

I think the section Getting a Plugin’s Bash Tag Suggestions in the loot api python documentation could be updated to the following code to reflect the need to run initialise_locale() beforehand and the fact that the second argument to create_game_handle() is now required:

>>> import loot_api
>>> loot_api.initialise_locale('')
>>> game = loot_api.create_game_handle(loot_api.GameType.tes4, 'Path\\To\\Oblivion\\Folder')
>>> db = game.get_database()
>>> db.load_lists('masterlist.yaml')
>>> tags = db.get_plugin_tags(u'Unofficial Oblivion Patch.esp')
>>> tags.added
set([u'Scripts', u'Relations', u'C.Owner', u'Actors.AIPackages', u'Actors.Stats', u'Actors.ACBS', u'C.Music', u'Factions', u'Invent', u'Relev', u'Names', u'C.Light', u'Delev', u'C.Name', u'C.Climate', u'NPC.Class', u'Stats', u'Actors.DeathItem', u'Creatures.Blood', u'Actors.CombatStyle', u'Actors.AIData'])
>>> tags.removed
set([u'C.Water'])
>>> tags.userlist_modified
False

I do have a question about the locale. Should Wrye Bash call inisialise_locale() with the systems locale or just with the empty string as in this example?

Ortham commented 6 years ago

I'll update the docs. If you pass an empty string to initialise_locale() it will use the system locale, I'll document that and make an empty string the default value, so you can call it with no args if you don't need to do anything special.

Ortham commented 6 years ago

OK, closing this as the master branch has an updated usage example, an initialise_locale() function that can be called with a default parameter of "", and a create_game_handle() function that doesn't have a default value for its game_path parameter.