Repository: Flexget/Flexget

Issue:
Serialization and Trakt (?)
Previously discussed via chat
  
#### Log:
<details>
 <summary>(click to expand)</summary>

```
2020-01-30 15:20:27 ERROR    entry         download-anime-series-rss BUG: Lazy lookup was not compatible with serialization. Please file a bug report: `<function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>` of type <class 'function'> is not serializable
Traceback (most recent call last):

  File "c:\python37\Lib\threading.py", line 890, in _bootstrap
    self._bootstrap_inner()
    │    └ <function Thread._bootstrap_inner at 0x0000019F98F339D8>
    └ <Thread(task_queue, started daemon 6004)>

  File "c:\python37\Lib\threading.py", line 926, in _bootstrap_inner
    self.run()
    │    └ <function Thread.run at 0x0000019F98F33798>
    └ <Thread(task_queue, started daemon 6004)>

  File "c:\python37\Lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
    │    │        │    │        │    └ {}
    │    │        │    │        └ <Thread(task_queue, started daemon 6004)>
    │    │        │    └ ()
    │    │        └ <Thread(task_queue, started daemon 6004)>
    │    └ <bound method TaskQueue.run of <flexget.task_queue.TaskQueue object at 0x0000019F9F5D8A88>>
    └ <Thread(task_queue, started daemon 6004)>

  File "c:\users\brutuz\documents\github\flexget\flexget\task_queue.py", line 45, in run
    self.current_task.execute()
    │    │            └ <function Task.execute at 0x0000019F9B547168>
    │    └ <flexget.task.Task object at 0x0000019FA3E51348>
    └ <flexget.task_queue.TaskQueue object at 0x0000019F9F5D8A88>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 79, in wrapper
    return func(self, *args, **kw)
           │    │      │       └ {}
           │    │      └ ()
           │    └ <flexget.task.Task object at 0x0000019FA3E51348>
           └ <function Task.execute at 0x0000019F9B5470D8>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 696, in execute
    self._execute()
    │    └ <function Task._execute at 0x0000019F9B547048>
    └ <flexget.task.Task object at 0x0000019FA3E51348>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 662, in _execute
    self.__run_task_phase(phase)
    │                     └ 'output'
    └ <flexget.task.Task object at 0x0000019FA3E51348>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 488, in __run_task_phase
    response = self.__run_plugin(plugin, phase, args)
               │                 │       │      └ (<flexget.task.Task object at 0x0000019FA3E51348>, [{'entry_list': 'testy'}, {'trakt_list': {'account': 'brutuz', 'list': 'co...
               │                 │       └ 'output'
               │                 └ <PluginInfo(name=list_add)>
               └ <flexget.task.Task object at 0x0000019FA3E51348>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 521, in __run_plugin
    result = method(*args, **kwargs)
             │       │       └ {}
             │       └ (<flexget.task.Task object at 0x0000019FA3E51348>, [{'entry_list': 'testy'}, {'trakt_list': {'account': 'brutuz', 'list': 'co...
             └ <Event(name=plugin.list_add.output,func=on_task_output,priority=0)>

  File "c:\users\brutuz\documents\github\flexget\flexget\event.py", line 20, in __call__
    return self.func(*args, **kwargs)
           │    │     │       └ {}
           │    │     └ (<flexget.task.Task object at 0x0000019FA3E51348>, [{'entry_list': 'testy'}, {'trakt_list': {'account': 'brutuz', 'list': 'co...
           │    └ <bound method ListAdd.on_task_output of <flexget.components.managed_lists.list_add.ListAdd object at 0x0000019F9E2274C8>>
           └ <Event(name=plugin.list_add.output,func=on_task_output,priority=0)>

  File "c:\users\brutuz\documents\github\flexget\flexget\components\managed_lists\list_add.py", line 53, in on_task_output
    thelist |= task.accepted
    │          │    └ <property object at 0x0000019F9B546728>
    │          └ <flexget.task.Task object at 0x0000019FA3E51348>
    └ <flexget.components.managed_lists.lists.entry_list.db.DBEntrySet object at 0x0000019FA5487788>

  File "c:\users\brutuz\documents\github\flexget\lib\_collections_abc.py", line 606, in __ior__
    self.add(value)
    │    │   └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
    │    └ <function DBEntrySet.add at 0x0000019F9E6A6F78>
    └ <flexget.components.managed_lists.lists.entry_list.db.DBEntrySet object at 0x0000019FA5487788>

  File "c:\users\brutuz\documents\github\flexget\flexget\components\managed_lists\lists\entry_list\db.py", line 157, in add
    stored_entry = EntryListEntry(entry=entry, entry_list_id=self._db_list(session).id)
                   │                    │                    │    │        └ <sqlalchemy.orm.session.ContextSession object at 0x0000019FA5488808>
                   │                    │                    │    └ <function DBEntrySet._db_list at 0x0000019F9E6A68B8>
                   │                    │                    └ <flexget.components.managed_lists.lists.entry_list.db.DBEntrySet object at 0x0000019FA5487788>
                   │                    └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
                   └ <class 'flexget.components.managed_lists.lists.entry_list.db.EntryListEntry'>

  File "<string>", line 4, in __init__

  File "c:\users\brutuz\documents\github\flexget\lib\site-packages\sqlalchemy\orm\state.py", line 438, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
           │       │              │            └ {}
           │       │              └ (<sqlalchemy.orm.state.InstanceState object at 0x0000019FA5942948>, <EntryListEntry,title=[HorribleSubs] Jibaku Shounen Hanak...
           │       └ <function EntryListEntry.__init__ at 0x0000019F9E697A68>
           └ <ClassManager of <class 'flexget.components.managed_lists.lists.entry_list.db.EntryListEntry'> at 19f9e693e88>

  File "c:\users\brutuz\documents\github\flexget\flexget\components\managed_lists\lists\entry_list\db.py", line 80, in __init__
    self.entry = entry
    │    │       └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
    │    └ <sqlalchemy.orm.attributes.create_proxied_attribute.<locals>.Proxy object at 0x0000019F9E6A7048>
    └ <EntryListEntry,title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,original_url=magnet:?xt=urn:btih:YWFSDQGOT2RQ7...

  File "<string>", line 1, in __set__

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\database.py", line 94, in setter
    setattr(self, name, serialization.dumps(entry))
            │     │     │             │     └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
            │     │     │             └ <function dumps at 0x0000019F9B164678>
            │     │     └ <module 'flexget.utils.serialization' from 'c:\\users\\brutuz\\documents\\github\\flexget\\flexget\\utils\\serialization.py'>
            │     └ '_json'
            └ <EntryListEntry,title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,original_url=magnet:?xt=urn:btih:YWFSDQGOT2RQ7...

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 53, in dumps
    serialized = serialize(value)
                 │         └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
                 └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 21, in serialize
    'value': s.serialize(value),
             │ │         └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
             │ └ <classmethod object at 0x0000019F9B367048>
             └ <class 'flexget.entry.Entry'>

> File "c:\users\brutuz\documents\github\flexget\flexget\entry.py", line 314, in serialize
    lazy_lookups.append(serialize(ll))
    │            │      │         └ ('trakt_lazy_lookup', ['trakt_actors'], ({'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}, <boun...
    │            │      └ <function serialize at 0x0000019F9B157DC8>
    │            └ <method 'append' of 'list' objects>
    └ [{'serializer': 'TupleSerializer', 'version': 1, 'value': ['quality', ['quality'], None, None]}, {'serializer': 'TupleSeriali...

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 21, in serialize
    'value': s.serialize(value),
             │ │         └ ('trakt_lazy_lookup', ['trakt_actors'], ({'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}, <boun...
             │ └ <classmethod object at 0x0000019F9B196E88>
             └ <class 'flexget.utils.serialization.TupleSerializer'>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 157, in serialize
    return serialize(list(value))
           │              └ ('trakt_lazy_lookup', ['trakt_actors'], ({'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}, <boun...
           └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in serialize
    return [serialize(v) for v in value]
            │                     └ ['trakt_lazy_lookup', ['trakt_actors'], ({'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}, <boun...
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in <listcomp>
    return [serialize(v) for v in value]
            │         │      └ ({'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}, <bound method PluginTraktLookup._get_series o...
            │         └ ({'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}, <bound method PluginTraktLookup._get_series o...
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 21, in serialize
    'value': s.serialize(value),
             │ │         └ ({'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}, <bound method PluginTraktLookup._get_series o...
             │ └ <classmethod object at 0x0000019F9B196E88>
             └ <class 'flexget.utils.serialization.TupleSerializer'>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 157, in serialize
    return serialize(list(value))
           │              └ ({'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}, <bound method PluginTraktLookup._get_series o...
           └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in serialize
    return [serialize(v) for v in value]
            │                     └ [{'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}, <bound method PluginTraktLookup._get_series o...
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in <listcomp>
    return [serialize(v) for v in value]
            │         │      └ {'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}
            │         └ {'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 26, in serialize
    return {k: serialize(v) for k, v in value.items()}
               │                        │     └ <method 'items' of 'dict' objects>
               │                        └ {'trakt_actors': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>}
               └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 26, in <dictcomp>
    return {k: serialize(v) for k, v in value.items()}
            │  │         │      │  └ <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>
            │  │         │      └ 'trakt_actors'
            │  │         └ <function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>
            │  └ <function serialize at 0x0000019F9B157DC8>
            └ 'trakt_actors'

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 29, in serialize
    raise TypeError(f'`{value!r}` of type {type(value)!r} is not serializable')

TypeError: `<function PluginTraktLookup.<lambda> at 0x0000019F9F4C45E8>` of type <class 'function'> is not serializable
2020-01-30 15:20:27 ERROR    entry         download-anime-series-rss BUG: Lazy lookup was not compatible with serialization. Please file a bug report: `<function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>` of type <class 'function'> is not serializable
Traceback (most recent call last):

  File "c:\python37\Lib\threading.py", line 890, in _bootstrap
    self._bootstrap_inner()
    │    └ <function Thread._bootstrap_inner at 0x0000019F98F339D8>
    └ <Thread(task_queue, started daemon 6004)>

  File "c:\python37\Lib\threading.py", line 926, in _bootstrap_inner
    self.run()
    │    └ <function Thread.run at 0x0000019F98F33798>
    └ <Thread(task_queue, started daemon 6004)>

  File "c:\python37\Lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
    │    │        │    │        │    └ {}
    │    │        │    │        └ <Thread(task_queue, started daemon 6004)>
    │    │        │    └ ()
    │    │        └ <Thread(task_queue, started daemon 6004)>
    │    └ <bound method TaskQueue.run of <flexget.task_queue.TaskQueue object at 0x0000019F9F5D8A88>>
    └ <Thread(task_queue, started daemon 6004)>

  File "c:\users\brutuz\documents\github\flexget\flexget\task_queue.py", line 45, in run
    self.current_task.execute()
    │    │            └ <function Task.execute at 0x0000019F9B547168>
    │    └ <flexget.task.Task object at 0x0000019FA3E51348>
    └ <flexget.task_queue.TaskQueue object at 0x0000019F9F5D8A88>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 79, in wrapper
    return func(self, *args, **kw)
           │    │      │       └ {}
           │    │      └ ()
           │    └ <flexget.task.Task object at 0x0000019FA3E51348>
           └ <function Task.execute at 0x0000019F9B5470D8>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 696, in execute
    self._execute()
    │    └ <function Task._execute at 0x0000019F9B547048>
    └ <flexget.task.Task object at 0x0000019FA3E51348>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 662, in _execute
    self.__run_task_phase(phase)
    │                     └ 'output'
    └ <flexget.task.Task object at 0x0000019FA3E51348>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 488, in __run_task_phase
    response = self.__run_plugin(plugin, phase, args)
               │                 │       │      └ (<flexget.task.Task object at 0x0000019FA3E51348>, [{'entry_list': 'testy'}, {'trakt_list': {'account': 'brutuz', 'list': 'co...
               │                 │       └ 'output'
               │                 └ <PluginInfo(name=list_add)>
               └ <flexget.task.Task object at 0x0000019FA3E51348>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 521, in __run_plugin
    result = method(*args, **kwargs)
             │       │       └ {}
             │       └ (<flexget.task.Task object at 0x0000019FA3E51348>, [{'entry_list': 'testy'}, {'trakt_list': {'account': 'brutuz', 'list': 'co...
             └ <Event(name=plugin.list_add.output,func=on_task_output,priority=0)>

  File "c:\users\brutuz\documents\github\flexget\flexget\event.py", line 20, in __call__
    return self.func(*args, **kwargs)
           │    │     │       └ {}
           │    │     └ (<flexget.task.Task object at 0x0000019FA3E51348>, [{'entry_list': 'testy'}, {'trakt_list': {'account': 'brutuz', 'list': 'co...
           │    └ <bound method ListAdd.on_task_output of <flexget.components.managed_lists.list_add.ListAdd object at 0x0000019F9E2274C8>>
           └ <Event(name=plugin.list_add.output,func=on_task_output,priority=0)>

  File "c:\users\brutuz\documents\github\flexget\flexget\components\managed_lists\list_add.py", line 53, in on_task_output
    thelist |= task.accepted
    │          │    └ <property object at 0x0000019F9B546728>
    │          └ <flexget.task.Task object at 0x0000019FA3E51348>
    └ <flexget.components.managed_lists.lists.entry_list.db.DBEntrySet object at 0x0000019FA5487788>

  File "c:\users\brutuz\documents\github\flexget\lib\_collections_abc.py", line 606, in __ior__
    self.add(value)
    │    │   └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
    │    └ <function DBEntrySet.add at 0x0000019F9E6A6F78>
    └ <flexget.components.managed_lists.lists.entry_list.db.DBEntrySet object at 0x0000019FA5487788>

  File "c:\users\brutuz\documents\github\flexget\flexget\components\managed_lists\lists\entry_list\db.py", line 157, in add
    stored_entry = EntryListEntry(entry=entry, entry_list_id=self._db_list(session).id)
                   │                    │                    │    │        └ <sqlalchemy.orm.session.ContextSession object at 0x0000019FA5488808>
                   │                    │                    │    └ <function DBEntrySet._db_list at 0x0000019F9E6A68B8>
                   │                    │                    └ <flexget.components.managed_lists.lists.entry_list.db.DBEntrySet object at 0x0000019FA5487788>
                   │                    └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
                   └ <class 'flexget.components.managed_lists.lists.entry_list.db.EntryListEntry'>

  File "<string>", line 4, in __init__

  File "c:\users\brutuz\documents\github\flexget\lib\site-packages\sqlalchemy\orm\state.py", line 438, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
           │       │              │            └ {}
           │       │              └ (<sqlalchemy.orm.state.InstanceState object at 0x0000019FA5942948>, <EntryListEntry,title=[HorribleSubs] Jibaku Shounen Hanak...
           │       └ <function EntryListEntry.__init__ at 0x0000019F9E697A68>
           └ <ClassManager of <class 'flexget.components.managed_lists.lists.entry_list.db.EntryListEntry'> at 19f9e693e88>

  File "c:\users\brutuz\documents\github\flexget\flexget\components\managed_lists\lists\entry_list\db.py", line 80, in __init__
    self.entry = entry
    │    │       └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
    │    └ <sqlalchemy.orm.attributes.create_proxied_attribute.<locals>.Proxy object at 0x0000019F9E6A7048>
    └ <EntryListEntry,title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,original_url=magnet:?xt=urn:btih:YWFSDQGOT2RQ7...

  File "<string>", line 1, in __set__

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\database.py", line 94, in setter
    setattr(self, name, serialization.dumps(entry))
            │     │     │             │     └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
            │     │     │             └ <function dumps at 0x0000019F9B164678>
            │     │     └ <module 'flexget.utils.serialization' from 'c:\\users\\brutuz\\documents\\github\\flexget\\flexget\\utils\\serialization.py'>
            │     └ '_json'
            └ <EntryListEntry,title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,original_url=magnet:?xt=urn:btih:YWFSDQGOT2RQ7...

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 53, in dumps
    serialized = serialize(value)
                 │         └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
                 └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 21, in serialize
    'value': s.serialize(value),
             │ │         └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
             │ └ <classmethod object at 0x0000019F9B367048>
             └ <class 'flexget.entry.Entry'>

> File "c:\users\brutuz\documents\github\flexget\flexget\entry.py", line 314, in serialize
    lazy_lookups.append(serialize(ll))
    │            │      │         └ ('trakt_lazy_lookup', ['trakt_translations'], ({'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4...
    │            │      └ <function serialize at 0x0000019F9B157DC8>
    │            └ <method 'append' of 'list' objects>
    └ [{'serializer': 'TupleSerializer', 'version': 1, 'value': ['quality', ['quality'], None, None]}, {'serializer': 'TupleSeriali...

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 21, in serialize
    'value': s.serialize(value),
             │ │         └ ('trakt_lazy_lookup', ['trakt_translations'], ({'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4...
             │ └ <classmethod object at 0x0000019F9B196E88>
             └ <class 'flexget.utils.serialization.TupleSerializer'>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 157, in serialize
    return serialize(list(value))
           │              └ ('trakt_lazy_lookup', ['trakt_translations'], ({'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4...
           └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in serialize
    return [serialize(v) for v in value]
            │                     └ ['trakt_lazy_lookup', ['trakt_translations'], ({'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4...
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in <listcomp>
    return [serialize(v) for v in value]
            │         │      └ ({'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>}, <bound method PluginTraktLookup._get_se...
            │         └ ({'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>}, <bound method PluginTraktLookup._get_se...
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 21, in serialize
    'value': s.serialize(value),
             │ │         └ ({'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>}, <bound method PluginTraktLookup._get_se...
             │ └ <classmethod object at 0x0000019F9B196E88>
             └ <class 'flexget.utils.serialization.TupleSerializer'>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 157, in serialize
    return serialize(list(value))
           │              └ ({'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>}, <bound method PluginTraktLookup._get_se...
           └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in serialize
    return [serialize(v) for v in value]
            │                     └ [{'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>}, <bound method PluginTraktLookup._get_se...
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in <listcomp>
    return [serialize(v) for v in value]
            │         │      └ {'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>}
            │         └ {'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>}
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 26, in serialize
    return {k: serialize(v) for k, v in value.items()}
               │                        │     └ <method 'items' of 'dict' objects>
               │                        └ {'trakt_translations': <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>}
               └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 26, in <dictcomp>
    return {k: serialize(v) for k, v in value.items()}
            │  │         │      │  └ <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>
            │  │         │      └ 'trakt_translations'
            │  │         └ <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>
            │  └ <function serialize at 0x0000019F9B157DC8>
            └ 'trakt_translations'

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 29, in serialize
    raise TypeError(f'`{value!r}` of type {type(value)!r} is not serializable')

TypeError: `<function PluginTraktLookup.<lambda> at 0x0000019F9F4C4678>` of type <class 'function'> is not serializable
2020-01-30 15:20:27 ERROR    entry         download-anime-series-rss BUG: Lazy lookup was not compatible with serialization. Please file a bug report: `<function PluginTraktLookup.<lambda> at 0x0000019F9F4C4708>` of type <class 'function'> is not serializable
Traceback (most recent call last):

  File "c:\python37\Lib\threading.py", line 890, in _bootstrap
    self._bootstrap_inner()
    │    └ <function Thread._bootstrap_inner at 0x0000019F98F339D8>
    └ <Thread(task_queue, started daemon 6004)>

  File "c:\python37\Lib\threading.py", line 926, in _bootstrap_inner
    self.run()
    │    └ <function Thread.run at 0x0000019F98F33798>
    └ <Thread(task_queue, started daemon 6004)>

  File "c:\python37\Lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
    │    │        │    │        │    └ {}
    │    │        │    │        └ <Thread(task_queue, started daemon 6004)>
    │    │        │    └ ()
    │    │        └ <Thread(task_queue, started daemon 6004)>
    │    └ <bound method TaskQueue.run of <flexget.task_queue.TaskQueue object at 0x0000019F9F5D8A88>>
    └ <Thread(task_queue, started daemon 6004)>

  File "c:\users\brutuz\documents\github\flexget\flexget\task_queue.py", line 45, in run
    self.current_task.execute()
    │    │            └ <function Task.execute at 0x0000019F9B547168>
    │    └ <flexget.task.Task object at 0x0000019FA3E51348>
    └ <flexget.task_queue.TaskQueue object at 0x0000019F9F5D8A88>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 79, in wrapper
    return func(self, *args, **kw)
           │    │      │       └ {}
           │    │      └ ()
           │    └ <flexget.task.Task object at 0x0000019FA3E51348>
           └ <function Task.execute at 0x0000019F9B5470D8>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 696, in execute
    self._execute()
    │    └ <function Task._execute at 0x0000019F9B547048>
    └ <flexget.task.Task object at 0x0000019FA3E51348>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 662, in _execute
    self.__run_task_phase(phase)
    │                     └ 'output'
    └ <flexget.task.Task object at 0x0000019FA3E51348>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 488, in __run_task_phase
    response = self.__run_plugin(plugin, phase, args)
               │                 │       │      └ (<flexget.task.Task object at 0x0000019FA3E51348>, [{'entry_list': 'testy'}, {'trakt_list': {'account': 'brutuz', 'list': 'co...
               │                 │       └ 'output'
               │                 └ <PluginInfo(name=list_add)>
               └ <flexget.task.Task object at 0x0000019FA3E51348>

  File "c:\users\brutuz\documents\github\flexget\flexget\task.py", line 521, in __run_plugin
    result = method(*args, **kwargs)
             │       │       └ {}
             │       └ (<flexget.task.Task object at 0x0000019FA3E51348>, [{'entry_list': 'testy'}, {'trakt_list': {'account': 'brutuz', 'list': 'co...
             └ <Event(name=plugin.list_add.output,func=on_task_output,priority=0)>

  File "c:\users\brutuz\documents\github\flexget\flexget\event.py", line 20, in __call__
    return self.func(*args, **kwargs)
           │    │     │       └ {}
           │    │     └ (<flexget.task.Task object at 0x0000019FA3E51348>, [{'entry_list': 'testy'}, {'trakt_list': {'account': 'brutuz', 'list': 'co...
           │    └ <bound method ListAdd.on_task_output of <flexget.components.managed_lists.list_add.ListAdd object at 0x0000019F9E2274C8>>
           └ <Event(name=plugin.list_add.output,func=on_task_output,priority=0)>

  File "c:\users\brutuz\documents\github\flexget\flexget\components\managed_lists\list_add.py", line 53, in on_task_output
    thelist |= task.accepted
    │          │    └ <property object at 0x0000019F9B546728>
    │          └ <flexget.task.Task object at 0x0000019FA3E51348>
    └ <flexget.components.managed_lists.lists.entry_list.db.DBEntrySet object at 0x0000019FA5487788>

  File "c:\users\brutuz\documents\github\flexget\lib\_collections_abc.py", line 606, in __ior__
    self.add(value)
    │    │   └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
    │    └ <function DBEntrySet.add at 0x0000019F9E6A6F78>
    └ <flexget.components.managed_lists.lists.entry_list.db.DBEntrySet object at 0x0000019FA5487788>

  File "c:\users\brutuz\documents\github\flexget\flexget\components\managed_lists\lists\entry_list\db.py", line 157, in add
    stored_entry = EntryListEntry(entry=entry, entry_list_id=self._db_list(session).id)
                   │                    │                    │    │        └ <sqlalchemy.orm.session.ContextSession object at 0x0000019FA5488808>
                   │                    │                    │    └ <function DBEntrySet._db_list at 0x0000019F9E6A68B8>
                   │                    │                    └ <flexget.components.managed_lists.lists.entry_list.db.DBEntrySet object at 0x0000019FA5487788>
                   │                    └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
                   └ <class 'flexget.components.managed_lists.lists.entry_list.db.EntryListEntry'>

  File "<string>", line 4, in __init__

  File "c:\users\brutuz\documents\github\flexget\lib\site-packages\sqlalchemy\orm\state.py", line 438, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
           │       │              │            └ {}
           │       │              └ (<sqlalchemy.orm.state.InstanceState object at 0x0000019FA5942948>, <EntryListEntry,title=[HorribleSubs] Jibaku Shounen Hanak...
           │       └ <function EntryListEntry.__init__ at 0x0000019F9E697A68>
           └ <ClassManager of <class 'flexget.components.managed_lists.lists.entry_list.db.EntryListEntry'> at 19f9e693e88>

  File "c:\users\brutuz\documents\github\flexget\flexget\components\managed_lists\lists\entry_list\db.py", line 80, in __init__
    self.entry = entry
    │    │       └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
    │    └ <sqlalchemy.orm.attributes.create_proxied_attribute.<locals>.Proxy object at 0x0000019F9E6A7048>
    └ <EntryListEntry,title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,original_url=magnet:?xt=urn:btih:YWFSDQGOT2RQ7...

  File "<string>", line 1, in __set__

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\database.py", line 94, in setter
    setattr(self, name, serialization.dumps(entry))
            │     │     │             │     └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
            │     │     │             └ <function dumps at 0x0000019F9B164678>
            │     │     └ <module 'flexget.utils.serialization' from 'c:\\users\\brutuz\\documents\\github\\flexget\\flexget\\utils\\serialization.py'>
            │     └ '_json'
            └ <EntryListEntry,title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,original_url=magnet:?xt=urn:btih:YWFSDQGOT2RQ7...

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 53, in dumps
    serialized = serialize(value)
                 │         └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
                 └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 21, in serialize
    'value': s.serialize(value),
             │ │         └ <Entry(title=[HorribleSubs] Jibaku Shounen Hanako-kun - 04 [720p].mkv,state=accepted)>
             │ └ <classmethod object at 0x0000019F9B367048>
             └ <class 'flexget.entry.Entry'>

> File "c:\users\brutuz\documents\github\flexget\flexget\entry.py", line 314, in serialize
    lazy_lookups.append(serialize(ll))
    │            │      │         └ ('trakt_lazy_lookup', ['trakt_ep_name', 'trakt_ep_imdb_id', 'trakt_ep_tvdb_id', 'trakt_ep_tmdb_id', 'trakt_ep_tvrage', 'trakt...
    │            │      └ <function serialize at 0x0000019F9B157DC8>
    │            └ <method 'append' of 'list' objects>
    └ [{'serializer': 'TupleSerializer', 'version': 1, 'value': ['quality', ['quality'], None, None]}, {'serializer': 'TupleSeriali...

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 21, in serialize
    'value': s.serialize(value),
             │ │         └ ('trakt_lazy_lookup', ['trakt_ep_name', 'trakt_ep_imdb_id', 'trakt_ep_tvdb_id', 'trakt_ep_tmdb_id', 'trakt_ep_tvrage', 'trakt...
             │ └ <classmethod object at 0x0000019F9B196E88>
             └ <class 'flexget.utils.serialization.TupleSerializer'>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 157, in serialize
    return serialize(list(value))
           │              └ ('trakt_lazy_lookup', ['trakt_ep_name', 'trakt_ep_imdb_id', 'trakt_ep_tvdb_id', 'trakt_ep_tmdb_id', 'trakt_ep_tvrage', 'trakt...
           └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in serialize
    return [serialize(v) for v in value]
            │                     └ ['trakt_lazy_lookup', ['trakt_ep_name', 'trakt_ep_imdb_id', 'trakt_ep_tvdb_id', 'trakt_ep_tmdb_id', 'trakt_ep_tvrage', 'trakt...
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in <listcomp>
    return [serialize(v) for v in value]
            │         │      └ ({'trakt_ep_name': 'title', 'trakt_ep_imdb_id': 'imdb_id', 'trakt_ep_tvdb_id': 'tvdb_id', 'trakt_ep_tmdb_id': 'tmdb_id', 'tra...
            │         └ ({'trakt_ep_name': 'title', 'trakt_ep_imdb_id': 'imdb_id', 'trakt_ep_tvdb_id': 'tvdb_id', 'trakt_ep_tmdb_id': 'tmdb_id', 'tra...
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 21, in serialize
    'value': s.serialize(value),
             │ │         └ ({'trakt_ep_name': 'title', 'trakt_ep_imdb_id': 'imdb_id', 'trakt_ep_tvdb_id': 'tvdb_id', 'trakt_ep_tmdb_id': 'tmdb_id', 'tra...
             │ └ <classmethod object at 0x0000019F9B196E88>
             └ <class 'flexget.utils.serialization.TupleSerializer'>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 157, in serialize
    return serialize(list(value))
           │              └ ({'trakt_ep_name': 'title', 'trakt_ep_imdb_id': 'imdb_id', 'trakt_ep_tvdb_id': 'tvdb_id', 'trakt_ep_tmdb_id': 'tmdb_id', 'tra...
           └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in serialize
    return [serialize(v) for v in value]
            │                     └ [{'trakt_ep_name': 'title', 'trakt_ep_imdb_id': 'imdb_id', 'trakt_ep_tvdb_id': 'tvdb_id', 'trakt_ep_tmdb_id': 'tmdb_id', 'tra...
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 24, in <listcomp>
    return [serialize(v) for v in value]
            │         │      └ {'trakt_ep_name': 'title', 'trakt_ep_imdb_id': 'imdb_id', 'trakt_ep_tvdb_id': 'tvdb_id', 'trakt_ep_tmdb_id': 'tmdb_id', 'trak...
            │         └ {'trakt_ep_name': 'title', 'trakt_ep_imdb_id': 'imdb_id', 'trakt_ep_tvdb_id': 'tvdb_id', 'trakt_ep_tmdb_id': 'tmdb_id', 'trak...
            └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 26, in serialize
    return {k: serialize(v) for k, v in value.items()}
               │                        │     └ <method 'items' of 'dict' objects>
               │                        └ {'trakt_ep_name': 'title', 'trakt_ep_imdb_id': 'imdb_id', 'trakt_ep_tvdb_id': 'tvdb_id', 'trakt_ep_tmdb_id': 'tmdb_id', 'trak...
               └ <function serialize at 0x0000019F9B157DC8>

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 26, in <dictcomp>
    return {k: serialize(v) for k, v in value.items()}
            │  │         │      │  └ <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4708>
            │  │         │      └ 'trakt_ep_id'
            │  │         └ <function PluginTraktLookup.<lambda> at 0x0000019F9F4C4708>
            │  └ <function serialize at 0x0000019F9B157DC8>
            └ 'trakt_ep_id'

  File "c:\users\brutuz\documents\github\flexget\flexget\utils\serialization.py", line 29, in serialize
    raise TypeError(f'`{value!r}` of type {type(value)!r} is not serializable')

TypeError: `<function PluginTraktLookup.<lambda> at 0x0000019F9F4C4708>` of type <class 'function'> is not serializable
```
</details>

### Additional information:

- FlexGet version: 3.1.15
- Python version: 3.7
- Installation method: git
- Using daemon (yes/no): yes
- OS and version: Win10


Discussion:

Resolving patch:
diff --git a/flexget/components/trakt/trakt_lookup.py b/flexget/components/trakt/trakt_lookup.py
--- a/flexget/components/trakt/trakt_lookup.py
+++ b/flexget/components/trakt/trakt_lookup.py
@@ -34,25 +34,25 @@ def is_movie(entry):
     return bool(entry.get('movie_name'))
 
 
-@entry.register_lazy_lookup('trakt_lazy_lookup')
-def trakt_lazy_lookup(entry, field_map, lookup_function):
-    with Session() as session:
-        try:
-            result = lookup_function(entry, session)
-        except LookupError as e:
-            logger.debug(e)
-        else:
-            entry.update_using_map(field_map, result)
-
-    return entry
+def get_media_type_for_entry(entry):
+    if is_episode(entry):
+        return 'episode'
+    elif is_season(entry):
+        return 'season'
+    elif is_show(entry):
+        return 'show'
+    elif is_movie(entry):
+        return 'movie'
 
 
 @entry.register_lazy_lookup('trakt_user_data_lookup')
-def trakt_user_data_lookup(entry, field_name, data_type, media_type, lookup_function):
+def trakt_user_data_lookup(entry, field_name, data_type, media_type, username, account):
+    trakt = plugin_api_trakt.ApiTrakt(username=username, account=account)
+    user_data_lookup = trakt.lookup_map[data_type][media_type]
+
     try:
-        result = lookup_function(
-            data_type=data_type, media_type=media_type, entry=entry
-        )
+        with Session() as session:
+            result = user_data_lookup(get_db_data_for(media_type, entry, session), entry['title'])
     except LookupError as e:
         logger.debug(e)
     else:
@@ -61,51 +61,48 @@ def trakt_user_data_lookup(entry, field_name, data_type, media_type, lookup_func
     return entry
 
 
-class PluginTraktLookup:
-    """Retrieves trakt information for entries. Uses series_name,
-    series_season, series_episode from series plugin.
-
-    Example:
-
-    trakt_lookup: yes
+def _get_lookup_args(entry):
+    args = {
+        'title': entry.get('series_name', eval_lazy=False) or entry.get('title', eval_lazy=False),
+        'year': entry.get('year', eval_lazy=False) or entry.get('movie_year', eval_lazy=False),
+        'trakt_slug': (
+            entry.get('trakt_show_slug', eval_lazy=False)
+            or entry.get('trakt_movie_slug', eval_lazy=False)
+        ),
+        'tmdb_id': entry.get('tmdb_id', eval_lazy=False),
+        'tvdb_id': entry.get('tvdb_id', eval_lazy=False),
+        'imdb_id': entry.get('imdb_id', eval_lazy=False),
+        'tvrage_id': entry.get('tvrage_id', eval_lazy=False),
+    }
 
-    Primarily used for passing trakt information to other plugins.
-    Among these is the IMDB url for the series.
+    if entry.get('trakt_movie_id', eval_lazy=False):
+        args['trakt_id'] = entry['trakt_movie_id']
+    elif entry.get('trakt_show_id', eval_lazy=False):
+        args['trakt_id'] = entry['trakt_show_id']
+    elif is_movie(entry) and entry.get('trakt_movie_id', eval_lazy=True):
+        args['trakt_id'] = entry['trakt_movie_id']
+    elif entry.get('trakt_show_id', eval_lazy=True):
+        args['trakt_id'] = entry['trakt_show_id']
 
-    This information is provided (via entry):
-    series info:
-    trakt_series_name
-    trakt_series_runtime
-    trakt_series_first_aired_epoch
-    trakt_series_first_aired_iso
-    trakt_series_air_time
-    trakt_series_content_ratingi
-    trakt_series_genres
-    trakt_series_imdb_url
-    trakt_series_trakt_url
-    imdb_id
-    tvdb_id
-    trakt_series_actors
-    trakt_series_country
-    trakt_series_year
-    trakt_series_tvrage_id
-    trakt_series_status
-    trakt_series_overview
+    return args
 
-    trakt_ep_name
-    trakt_ep_season
-    trakt_ep_number
-    trakt_ep_overview
-    trakt_ep_first_aired_epoch
-    trakt_ep_first_aired_iso
-    trakt_ep_id
-    trakt_ep_tvdb_id
 
+def get_db_data_for(data_type, entry, session):
+    if data_type == 'movie':
+        movie_lookup_args = _get_lookup_args(entry)
+        return lookup_movie(session=session, **movie_lookup_args)
+    series_lookup_args = _get_lookup_args(entry)
+    show = lookup_series(session=session, **series_lookup_args)
+    if data_type == 'show':
+        return show
+    if data_type == 'season':
+        return show.get_season(entry['series_season'], session)
+    if data_type == 'episode':
+        return show.get_episode(entry['series_season'], entry['series_episode'], session)
 
-    """
 
-    # Series info
-    series_map = {
+lazy_lookup_types = {
+    'show': {
         'trakt_series_name': 'title',
         'trakt_series_year': 'year',
         'imdb_id': 'imdb_id',
@@ -136,15 +133,24 @@ class PluginTraktLookup:
         'trakt_series_aired_episodes': 'aired_episodes',
         'trakt_series_episodes': lambda show: [episodes.title for episodes in show.episodes],
         'trakt_languages': 'translation_languages',
-    }
-
-    series_actor_map = {'trakt_actors': lambda show: db.list_actors(show.actors)}
-    show_translate_map = {
+    },
+    'show_actors': {'trakt_actors': lambda show: db.list_actors(show.actors)},
+    'show_translations': {
         'trakt_translations': lambda show: db.get_translations_dict(show.translations, 'show')
-    }
-
-    # Episode info
-    episode_map = {
+    },
+    'season': {
+        'trakt_season_name': 'title',
+        'trakt_season_tvdb_id': 'tvdb_id',
+        'trakt_season_tmdb_id': 'tmdb_id',
+        'trakt_season_tvrage': 'tvrage_id',
+        'trakt_season_id': 'id',
+        'trakt_season_first_aired': 'first_aired',
+        'trakt_season_overview': 'overview',
+        'trakt_season_episode_count': 'episode_count',
+        'trakt_season': 'number',
+        'trakt_season_aired_episodes': 'aired_episodes',
+    },
+    'episode': {
         'trakt_ep_name': 'title',
         'trakt_ep_imdb_id': 'imdb_id',
         'trakt_ep_tvdb_id': 'tvdb_id',
@@ -157,24 +163,8 @@ class PluginTraktLookup:
         'trakt_season': 'season',
         'trakt_episode': 'number',
         'trakt_ep_id': lambda ep: 'S%02dE%02d' % (ep.season, ep.number),
-    }
-
-    # Season info
-    season_map = {
-        'trakt_season_name': 'title',
-        'trakt_season_tvdb_id': 'tvdb_id',
-        'trakt_season_tmdb_id': 'tmdb_id',
-        'trakt_season_tvrage': 'tvrage_id',
-        'trakt_season_id': 'id',
-        'trakt_season_first_aired': 'first_aired',
-        'trakt_season_overview': 'overview',
-        'trakt_season_episode_count': 'episode_count',
-        'trakt_season': 'number',
-        'trakt_season_aired_episodes': 'aired_episodes',
-    }
-
-    # Movie info
-    movie_map = {
+    },
+    'movie': {
         'movie_name': 'title',
         'movie_year': 'year',
         'trakt_movie_name': 'title',
@@ -194,24 +184,115 @@ class PluginTraktLookup:
         'trakt_language': 'language',
         'trakt_genres': lambda i: [db_genre.name for db_genre in i.genres],
         'trakt_languages': 'translation_languages',
-    }
-
-    movie_translate_map = {
+    },
+    'movie_actors': {'trakt_actors': lambda movie: db.list_actors(movie.actors)},
+    'movie_translations': {
         'trakt_translations': lambda movie: db.get_translations_dict(movie.translations, 'movie')
-    }
+    },
+}
 
-    movie_actor_map = {'trakt_actors': lambda movie: db.list_actors(movie.actors)}
-
-    user_data_map = {
-        'collected': 'trakt_collected',
-        'watched': 'trakt_watched',
-        'ratings': {
-            'show': 'trakt_series_user_rating',
-            'season': 'trakt_season_user_rating',
-            'episode': 'trakt_ep_user_rating',
-            'movie': 'trakt_movie_user_rating',
-        },
-    }
+
+@entry.register_lazy_lookup('trakt_lazy_lookup')
+def lazy_lookup(entry, lazy_lookup_name, media_type):
+    with Session() as session:
+        try:
+            db_data = get_db_data_for(media_type, entry, session)
+        except LookupError as e:
+            logger.debug(e)
+        else:
+            entry.update_using_map(lazy_lookup_types[lazy_lookup_name], db_data)
+    return entry
+
+
+def add_lazy_fields(entry: entry.Entry, lazy_lookup_name: str, media_type: str):
+    """
+    Adds lazy fields for one of the lookups in our `lazy_lookup_types` dict.
+
+    :param entry: The entry to add lazy fields to.
+    :param lazy_lookup_name: One of the keys in `lazy_lookup_types` dict.
+    :param media_type: show/season/episode/movie (the type of db data needed for this lazy lookup)
+    """
+    entry.add_lazy_fields(
+        lazy_lookup, lazy_lookup_types[lazy_lookup_name], args=(lazy_lookup_name, media_type)
+    )
+
+
+user_data_fields = {
+    'collected': 'trakt_collected',
+    'watched': 'trakt_watched',
+    'ratings': {
+        'show': 'trakt_series_user_rating',
+        'season': 'trakt_season_user_rating',
+        'episode': 'trakt_ep_user_rating',
+        'movie': 'trakt_movie_user_rating',
+    },
+}
+
+
+def add_lazy_user_fields(
+    entry: entry.Entry, data_type: str, media_type: str, username: str, account: str
+):
+    """
+    Adds one of the user field lazy lookups to an entry.
+
+    :param entry: Entry to add lazy fields to
+    :param data_type: ratings/collected/watched (one of the keys in `user_data_fields` dict.)
+    :param media_type: show/season/episode/movie
+    :param username: Either this or account is required, the other can be None
+    :param account: Either this or username is required, the other can be None
+    """
+    field_name = user_data_fields[data_type]
+    if data_type == 'ratings':
+        field_name = field_name[media_type]
+    entry.add_lazy_fields(
+        trakt_user_data_lookup,
+        [field_name],
+        args=(field_name, data_type, media_type, username, account),
+    )
+
+
+class PluginTraktLookup:
+    """Retrieves trakt information for entries. Uses series_name,
+    series_season, series_episode from series plugin.
+
+    Example:
+
+    trakt_lookup: yes
+
+    Primarily used for passing trakt information to other plugins.
+    Among these is the IMDB url for the series.
+
+    This information is provided (via entry):
+    series info:
+    trakt_series_name
+    trakt_series_runtime
+    trakt_series_first_aired_epoch
+    trakt_series_first_aired_iso
+    trakt_series_air_time
+    trakt_series_content_ratingi
+    trakt_series_genres
+    trakt_series_imdb_url
+    trakt_series_trakt_url
+    imdb_id
+    tvdb_id
+    trakt_series_actors
+    trakt_series_country
+    trakt_series_year
+    trakt_series_tvrage_id
+    trakt_series_status
+    trakt_series_overview
+
+    trakt_ep_name
+    trakt_ep_season
+    trakt_ep_number
+    trakt_ep_overview
+    trakt_ep_first_aired_epoch
+    trakt_ep_first_aired_iso
+    trakt_ep_id
+    trakt_ep_tvdb_id
+
+
+    """
 
     schema = {
         'oneOf': [
@@ -226,14 +307,6 @@ class PluginTraktLookup:
         ]
     }
 
-    def __init__(self):
-        self.getter_map = {
-            'show': self._get_series,
-            'season': self._get_season,
-            'episode': self._get_episode,
-            'movie': self._get_movie,
-        }
-
     def on_task_start(self, task, config):
         if not isinstance(config, dict):
             config = {}
@@ -242,85 +315,6 @@ def on_task_start(self, task, config):
             username=config.get('username'), account=config.get('account')
         )
 
-    def _get_user_data_field_name(self, data_type, media_type):
-        if data_type not in self.user_data_map:
-            raise plugin.PluginError('Unknown user data type "%s"' % data_type)
-
-        if isinstance(self.user_data_map[data_type], dict):
-            return self.user_data_map[data_type][media_type]
-
-        return self.user_data_map[data_type]
-
-    def _get_lookup_args(self, entry):
-        args = {
-            'title': entry.get('series_name', eval_lazy=False)
-            or entry.get('title', eval_lazy=False),
-            'year': entry.get('year', eval_lazy=False),
-            'trakt_slug': (
-                entry.get('trakt_show_slug', eval_lazy=False)
-                or entry.get('trakt_movie_slug', eval_lazy=False)
-            ),
-            'tmdb_id': entry.get('tmdb_id', eval_lazy=False),
-            'tvdb_id': entry.get('tvdb_id', eval_lazy=False),
-            'imdb_id': entry.get('imdb_id', eval_lazy=False),
-            'tvrage_id': entry.get('tvrage_id', eval_lazy=False),
-        }
-
-        if entry.get('trakt_movie_id', eval_lazy=False):
-            args['trakt_id'] = entry['trakt_movie_id']
-        elif entry.get('trakt_show_id', eval_lazy=False):
-            args['trakt_id'] = entry['trakt_show_id']
-        elif is_movie(entry) and entry.get('trakt_movie_id', eval_lazy=True):
-            args['trakt_id'] = entry['trakt_movie_id']
-        elif entry.get('trakt_show_id', eval_lazy=True):
-            args['trakt_id'] = entry['trakt_show_id']
-
-        return args
-
-    def _get_series(self, entry, session):
-        series_lookup_args = self._get_lookup_args(entry)
-        return lookup_series(session=session, **series_lookup_args)
-
-    def _get_season(self, entry, session):
-        series_lookup_args = self._get_lookup_args(entry)
-        show = lookup_series(session=session, **series_lookup_args)
-        return show.get_season(entry['series_season'], session)
-
-    def _get_episode(self, entry, session):
-        series_lookup_args = self._get_lookup_args(entry)
-        show = lookup_series(session=session, **series_lookup_args)
-        return show.get_episode(entry['series_season'], entry['series_episode'], session)
-
-    def _get_movie(self, entry, session):
-        movie_lookup_args = self._get_lookup_args(entry)
-        return lookup_movie(session=session, **movie_lookup_args)
-
-    def lazy_lookup(self, entry, media_type, mapping):
-        """Does the lookup for this entry and populates the entry fields."""
-        with Session() as session:
-            try:
-                trakt_media = self.getter_map[media_type](entry, session)
-            except LookupError as e:
-                logger.debug(e)
-            else:
-                entry.update_using_map(mapping, trakt_media)
-        return entry
-
-    def _lazy_user_data_lookup(self, data_type, media_type, entry):
-        try:
-            lookup = self.getter_map[media_type]
-            user_data_lookup = self.trakt.lookup_map[data_type][media_type]
-        except KeyError:
-            raise plugin.PluginError(
-                'Unknown data type="%s" or media type="%s"' % (data_type, media_type)
-            )
-
-        with Session() as session:
-            try:
-                return user_data_lookup(lookup(entry, session), entry['title'])
-            except LookupError as e:
-                logger.debug(e)
-
     # Run after series and metainfo series
     @plugin.priority(110)
     def on_task_metainfo(self, task, config):
@@ -332,82 +326,34 @@ def on_task_metainfo(self, task, config):
 
         for entry in task.entries:
             if is_show(entry):
-                entry.add_lazy_fields(
-                    trakt_lazy_lookup, self.series_map, args=(self.series_map, self._get_series)
-                )
-                # TODO cleaner way to do this?
-                entry.add_lazy_fields(
-                    trakt_lazy_lookup, self.series_actor_map, args=(self.series_actor_map, self._get_series)
-                )
-                entry.add_lazy_fields(
-                    trakt_lazy_lookup, self.show_translate_map, args=(self.show_translate_map, self._get_series)
-                )
+                add_lazy_fields(entry, 'show', media_type='show')
+                add_lazy_fields(entry, 'show_actors', media_type='show')
+                add_lazy_fields(entry, 'show_translations', media_type='show')
                 if is_episode(entry):
-                    entry.add_lazy_fields(
-                        trakt_lazy_lookup, self.episode_map, args=(self.episode_map, self._get_episode)
-                    )
+                    add_lazy_fields(entry, 'episode', media_type='episode')
                 elif is_season(entry):
-                    entry.add_lazy_fields(
-                        trakt_lazy_lookup, self.season_map, args=(self.season_map, self._get_season)
-                    )
+                    add_lazy_fields(entry, 'season', media_type='season')
             else:
-                entry.add_lazy_fields(
-                    trakt_lazy_lookup, self.movie_map, args=(self.movie_map, self._get_movie)
-                )
-                # TODO cleaner way to do this?
-                entry.add_lazy_fields(
-                    trakt_lazy_lookup, self.movie_actor_map, args=(self.movie_actor_map, self._get_movie)
-                )
-                entry.add_lazy_fields(
-                    trakt_lazy_lookup,
-                    self.movie_translate_map, args=(self.movie_translate_map, self._get_movie)
-                )
+                add_lazy_fields(entry, 'movie', media_type='movie')
+                add_lazy_fields(entry, 'movie_actors', media_type='movie')
+                add_lazy_fields(entry, 'movie_translations', media_type='movie')
 
             if config.get('username') or config.get('account'):
-                self._register_lazy_user_data_lookup(entry, 'collected')
-                self._register_lazy_user_data_lookup(entry, 'watched')
-                self._register_lazy_user_ratings_lookup(entry)
-
-    def _get_media_type_from_entry(self, entry):
-        media_type = None
-        if is_episode(entry):
-            media_type = 'episode'
-        elif is_season(entry):
-            media_type = 'season'
-        elif is_show(entry):
-            media_type = 'show'
-        elif is_movie(entry):
-            media_type = 'movie'
-
-        return media_type
-
-    def _register_lazy_user_data_lookup(self, entry, data_type, media_type=None):
-        media_type = media_type or self._get_media_type_from_entry(entry)
-        if not media_type:
-            return
-        field_name = self._get_user_data_field_name(data_type=data_type, media_type=media_type)
-        entry.add_lazy_fields(
-            trakt_user_data_lookup,
-            [field_name], args=(field_name, data_type, media_type, self._lazy_user_data_lookup)
-        )
-
-    def _register_lazy_user_ratings_lookup(self, entry):
-        data_type = 'ratings'
-
-        if is_show(entry):
-            self._register_lazy_user_data_lookup(
-                entry=entry, data_type=data_type, media_type='show'
-            )
-            self._register_lazy_user_data_lookup(
-                entry=entry, data_type=data_type, media_type='season'
-            )
-            self._register_lazy_user_data_lookup(
-                entry=entry, data_type=data_type, media_type='episode'
-            )
-        else:
-            self._register_lazy_user_data_lookup(
-                entry=entry, data_type=data_type, media_type='movie'
-            )
+                credentials = {
+                    'username': config.get('username'),
+                    'account': config.get('account'),
+                }
+                media_type = get_media_type_for_entry(entry)
+                add_lazy_user_fields(entry, 'collected', media_type=media_type, **credentials)
+                add_lazy_user_fields(entry, 'watched', media_type=media_type, **credentials)
+                if is_show(entry):
+                    add_lazy_user_fields(entry, 'ratings', media_type='show', **credentials)
+                    if is_season(entry):
+                        add_lazy_user_fields(entry, 'ratings', media_type='season', **credentials)
+                    if is_episode(entry):
+                        add_lazy_user_fields(entry, 'ratings', media_type='episode', **credentials)
+                elif is_movie(entry):
+                    add_lazy_user_fields(entry, 'ratings', media_type='movie', **credentials)
 
     @property
     def series_identifier(self):


Test patch: