Ух каша у вас какая-то тут из гипотез, суеверий, заблуждений и кусков кода, которые, как вам кажется, полностью обрисовывают проблему. А проблема у вас в том, что вы неправильно работаете с кодировками.
Общие правила работы с кодировками в питоне я уже много раз рассказывал на этом ресурсе.
На входе в программу мы всё переводим в юникод, а на выходе всё кодируем в байты.
Для ясности: юникод - это не кодировка, это абстрактный способ однозначной нумерации символов. Кодировка - это способ представить символ (а символ имеет свой однозначный код в таблице Юникода) в виде набора байт.
Итак, текст в юникоде - - это, образно говоря, последовтаельность номеров символов из таблицы юникода.
Текст в любой кодировке - это последовательность байтов.
Важно отметить, что так или инае номера юникода тоже внутри компа хранятся как байты, а питон с ними работает не как с массивом чисел, а как с объектом "строка", значит внутри он всё же хранит юникод в какой-то специальной кодировке, но тут есть важная деталь.
Есть кодировки, способные представить ВСЕ возможные символы Юникода, а есть кодировки, которые могут представить только некоторое подмножество этих символов. К первым относятся UTF-8, UTF-16, UTF-32 - они по-разному представляют номер символа таблицы Юникод в виде байтов, но способны представить любой символ.
Ко вторым, к примеру, однобайтовые кодировки cp1862, cp866, koi8 прочие. Такие кодировки - пережиток прошлого, когда в угоду простоте люди жертвовали универсальностью. Однако со временем, когда требоания к ПО и набору поддерживаемых символов изменилось, появилась необходимость как-то между этими кодировками переключаться, преобразовывать тексты, учитывать, что какойто текст без потери данных вовсе нельзя перевести из одной в другую кодировку, потому что каких то букв просто нет в целевой кодировке. Так простота накопилась техническим долгом и обернулась многократно возросшей сложностью учета всех этих нюансов.
В питоне внутри для хранения юникод-строк (а в 3 питоне это основной вид строк) используется не помню какая и utf-кодировок, но она точно может представить любой символ таблицы Юникода. И нам не нужно даже знать что это за кодировка, нам нужно знать какая кодировка на входе и на выходе программы.
У нас на входе и на выходе всегда байты. А именно:
- стандартные потоки ввода, вывода и ошибок, а также другие пайпы - это обычные байтовые потоки, которые работают ка коткрытые файлы, но являются пайпами на уровне системы и могут быть пернеправлены в реальные файлы в файловой сисеме.
- файлы - в файловой системе данные лежат в виде батов, и, в любом случае, нам нужно их как-то интерпретировать, если это текст.
Питон позволяет сделать обёртки вокруг файлового объекта, которые незаметно и прозрачно преобразовывают кодировки так что пользователь может в программе работать с юникодом не задумываясь о кодировках.
Всего лишь нужно правильно натсроить все эти обёртки и никогда не преобразовывать ничего вручную, а также не работать с байтовыми кодировками напрямую.
У вас, очевидно, self.task_name хранится в закодированном виде или некорректно преоразовывается.
Магии не бывает. Ничего там случайным образом с разу на раз не переключается. Если вы видете разные поведения в рахных ситуациях, то просто упускаете какой-то фактор. К примеру в винде запуск из bat-файла, запуск из консоли и запуск кликом мышкой в проводнике могут повлечь за собой запуск процесса с передачей ему пайпов стандартных потоков ввода вывода в разных кодировках. Если в программе мы этого не учитываем, то можем столкнуться с таким поведением как у вас.
Прологируйте значение вашего repr(self.task_name) перед взятием по ключу когда происходит ошибка и когда не происходит.
Вы увидите что меняется.