Python Exceções Embutidas
Quando algo dá errado, o Python para o programa e mostra o nome de uma exceção (exception, "exceção": um erro que acontece com o programa já rodando), como ValueError ou KeyError, seguido de uma mensagem. Esta página é o dicionário desses nomes: a árvore de famílias, a mensagem real que cada uma mostra no Python 3.14 e quando ela acontece. Para aprender a ler a mensagem inteira, veja a aula Lendo uma Mensagem de Erro; para tratar o erro, try e except.
- Exemplo é um código curto que provoca o erro; Mensagem real é a última linha do traceback que o Python 3.14.4 mostrou no computador da Ana. As mensagens do Python são sempre em inglês; a coluna "Quando acontece" traduz a ideia.
- A última linha tem sempre o formato
NomeDaExceção: explicação. Algumas exceções não têm explicação, e a linha é só o nome (por exemplo,StopIteration). - A coluna Aula leva à aula em que o erro aparece pela primeira vez.
Onde fica o nome da exceção
Um programa que usa uma variável que não existe:
$ python3 erro_nome.py
Traceback (most recent call last):
File "/home/ana/erro_nome.py", line 2, in <module>
print(nome)
^^^^
NameError: name 'nome' is not defined. Did you mean: 'nomes'?
Traceback (most recent call last):- "Rastro (a chamada mais recente por último)": o Python vai mostrar o caminho até o erro.
File "…", line 2- O arquivo e a linha onde o erro aconteceu.
^^^^- Os acentos marcam o pedaço exato da linha que deu problema.
NameError- O nome da exceção: é ele que você procura nesta página e é ele que vai no
except. name 'nome' is not defined. Did you mean: 'nomes'?- A explicação: "o nome 'nome' não está definido. Você quis dizer 'nomes'?". O Python 3.14 dá essas dicas quando acha um nome parecido.
A árvore de exceções
As exceções são classes organizadas em famílias, como uma árvore genealógica. Cada uma "é filha" de outra mais geral. Isso importa por um motivo prático: um except pega a exceção que você escreveu e todas as filhas dela. except LookupError pega IndexError e KeyError; except OSError pega todos os erros de arquivo.
Esta é a árvore das exceções embutidas do Python 3.14.4, montada pelo próprio Python no computador da Ana (cada nível de recuo é uma geração):
BaseException « a mãe de todas
├── BaseExceptionGroup
├── GeneratorExit
├── KeyboardInterrupt « Ctrl-C
├── SystemExit « sys.exit()
└── Exception « a mãe dos erros "normais"
├── ArithmeticError « contas
│ ├── FloatingPointError
│ ├── OverflowError
│ └── ZeroDivisionError
├── AssertionError
├── AttributeError
├── BufferError
├── EOFError
├── ExceptionGroup « filha de BaseExceptionGroup também
├── ImportError
│ └── ModuleNotFoundError
├── LookupError « procurar em listas e dicionários
│ ├── IndexError
│ └── KeyError
├── MemoryError
├── NameError
│ └── UnboundLocalError
├── OSError « arquivos, pastas, sistema, rede
│ ├── BlockingIOError
│ ├── ChildProcessError
│ ├── ConnectionError
│ │ ├── BrokenPipeError
│ │ ├── ConnectionAbortedError
│ │ ├── ConnectionRefusedError
│ │ └── ConnectionResetError
│ ├── FileExistsError
│ ├── FileNotFoundError
│ ├── InterruptedError
│ ├── IsADirectoryError
│ ├── NotADirectoryError
│ ├── PermissionError
│ ├── ProcessLookupError
│ └── TimeoutError
├── ReferenceError
├── RuntimeError
│ ├── NotImplementedError
│ ├── PythonFinalizationError
│ └── RecursionError
├── StopAsyncIteration
├── StopIteration
├── SyntaxError
│ └── IndentationError
│ └── TabError
├── SystemError
├── TypeError
├── ValueError
│ └── UnicodeError
│ ├── UnicodeDecodeError
│ ├── UnicodeEncodeError
│ └── UnicodeTranslateError
└── Warning « avisos (veja no fim da página)
├── BytesWarning
├── DeprecationWarning
├── EncodingWarning
├── FutureWarning
├── ImportWarning
├── PendingDeprecationWarning
├── ResourceWarning
├── RuntimeWarning
├── SyntaxWarning
├── UnicodeWarning
└── UserWarning
Você pode perguntar ao Python a "linha da família" de qualquer exceção com __mro__ (a ordem dos ancestrais) ou conferir um parentesco com issubclass ("é subclasse de?"):
print(ZeroDivisionError.__mro__) print(FileNotFoundError.__mro__) print(issubclass(KeyError, LookupError)) print(issubclass(KeyboardInterrupt, Exception))
$ python3 familia.py (<class 'ZeroDivisionError'>, <class 'ArithmeticError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>) (<class 'FileNotFoundError'>, <class 'OSError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>) True False
except BaseException (nem except: sozinho)
Repare na última linha: KeyboardInterrupt não é filha de Exception. Ela, SystemExit e GeneratorExit ficam de fora de propósito: não são "erros", são pedidos para o programa parar (o Ctrl-C do teclado, o sys.exit()). Um except Exception deixa esses pedidos passarem; um except BaseException ou um except: sem nome os engole, e o programa não para nem com Ctrl-C. Quando precisar de um "pega tudo", o mais largo aceitável é except Exception, e de preferência com o nome exato do erro que você espera.
A família ajuda a tratar vários erros parecidos de uma vez. O estoque da Ana tem um dicionário e uma lista; procurar algo que não existe dá KeyError num e IndexError na outra, e um único except LookupError pega os dois:
estoque = {"pão": 30, "leite": 12}
prateleira = ["pão", "leite"]
for tentativa in ["café", 5]:
try:
if isinstance(tentativa, str):
print(estoque[tentativa])
else:
print(prateleira[tentativa])
except LookupError as erro:
print(f"{type(erro).__name__}: {erro}")
$ python3 estoque.py KeyError: 'café' IndexError: list index out of range
Os erros do dia a dia
Estas são as exceções que um iniciante encontra quase todo dia.
| Exceção | Quando acontece | Exemplo | Mensagem real | Aula |
|---|---|---|---|---|
NameError | Usou um nome (variável, função) que não existe: erro de digitação ou variável criada depois. | nomes = ["Ana", "Bia"]print(nome) | NameError: name 'nome' is not defined. Did you mean: 'nomes'? | Variáveis |
UnboundLocalError | Dentro de uma função, mudou uma variável de fora sem global. | total = 0def somar(): total += 1somar() | UnboundLocalError: cannot access local variable 'total' where it is not associated with a value | Escopo |
TypeError | Juntou texto com número. | "Idade: " + 30 | TypeError: can only concatenate str (not "int") to str | Juntar Textos |
| Usou uma função num tipo que ela não aceita. | len(5) | TypeError: object of type 'int' has no len() | Funções Embutidas | |
| Chamou uma função sem um argumento obrigatório. | def saudar(nome): ...saudar() | TypeError: saudar() missing 1 required positional argument: 'nome' | Parâmetros | |
Pôs ( ) em algo que não é função. | None() | TypeError: 'NoneType' object is not callable | None | |
| Tentou mudar uma letra de um texto (textos não mudam). | "abc"[0] = "x" | TypeError: 'str' object does not support item assignment | Mutável × Imutável | |
| Usou uma lista como chave de dicionário. | {[1]: 2} | TypeError: cannot use 'list' as a dict key (unhashable type: 'list') | Dicionários | |
| Comparou número com texto. | 3 < "a" | TypeError: '<' not supported between instances of 'int' and 'str' | Comparações | |
ValueError | O tipo está certo, mas o valor não serve: texto que não é número. | int("dez") | ValueError: invalid literal for int() with base 10: 'dez' | Conversão de Tipos |
| Número com vírgula (o Python usa ponto). | float("1,5") | ValueError: could not convert string to float: '1,5' | Conversão de Tipos | |
| Tirou da lista um item que ela não tem. | [1, 2].remove(3) | ValueError: list.remove(x): x not in list | Removendo Itens | |
| Desempacotou com o número errado de variáveis. | a, b = [1, 2, 3] | ValueError: too many values to unpack (expected 2, got 3) | Desempacotamento | |
| Valor fora do que a conta aceita. | math.sqrt(-1) | ValueError: expected a nonnegative input, got -1.0 | O Módulo math | |
IndexError | Posição que não existe na lista. | ["pão", "leite"][5] | IndexError: list index out of range | Acessando Itens |
| Posição que não existe no texto. | "Ana"[10] | IndexError: string index out of range | Índices e Fatias | |
pop() numa lista vazia. | [].pop() | IndexError: pop from empty list | Removendo Itens | |
KeyError | Chave que não existe no dicionário. A mensagem é só a chave. | {"pão": 4.5}["café"] | KeyError: 'café' | Dicionários |
AttributeError | Método ou atributo que o valor não tem (muitas vezes, erro de digitação). | "ana".upercase() | AttributeError: 'str' object has no attribute 'upercase' | Métodos de Texto |
A variável ficou None e você chamou um método nela. | x = Nonex.append(1) | AttributeError: 'NoneType' object has no attribute 'append' | None | |
| Nome que o módulo não tem. | import mathmath.pi2 | AttributeError: module 'math' has no attribute 'pi2'. Did you mean: 'pi'? | Módulos e import | |
ZeroDivisionError | Divisão por zero. | 10 / 0 | ZeroDivisionError: division by zero | Operadores Aritméticos |
| O mesmo com a divisão inteira… | 10 // 0 | ZeroDivisionError: division by zero | ||
| …e com o resto. | 10 % 0 | ZeroDivisionError: division by zero |
TypeError ou ValueError?
TypeError = o tipo está errado (deu um número onde se esperava um texto). ValueError = o tipo está certo, mas o valor não serve (é um texto, mas "dez" não vira número). Em int("dez") o int aceita textos, só não esse.
Erros de escrita (antes de o programa rodar)
SyntaxError ("erro de sintaxe") e suas filhas são diferentes de todas as outras: o Python os encontra lendo o arquivo, antes de rodar a primeira linha. Por isso um try no mesmo arquivo não os pega: o programa nem começa. Cada mensagem abaixo vem com a linha e os ^ que o Python mostrou (arquivo teste.py).
| Exceção | Quando acontece | Exemplo | Mensagem real | Aula |
|---|---|---|---|---|
SyntaxError | Abriu um parêntese e não fechou. | print('oi' | SyntaxError: '(' was never closed | Sintaxe e Indentação |
| Esqueceu os dois-pontos. | if x == 1 | SyntaxError: expected ':' | if | |
| Abriu uma aspa e não fechou. | 'abc | SyntaxError: unterminated string literal (detected at line 1) | Strings | |
| O mesmo com três aspas. | """abc | SyntaxError: unterminated triple-quoted string literal (detected at line 1) | ||
print sem parênteses (jeito do Python 2). | print 'oi' | SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)? | print() | |
| Usou uma palavra-chave como nome de variável. | class = 1 | SyntaxError: invalid syntax | Nomes de Variáveis | |
| Expressão pela metade. | a = 1 + | SyntaxError: invalid syntax | ||
return fora de uma função. | return 5 | SyntaxError: 'return' outside function | return | |
IndentationError | Faltou recuar a linha depois do :. | def f():print(1) | IndentationError: expected an indented block after function definition on line 1 | Sintaxe e Indentação |
| Voltou para um recuo que não existia antes. | if True: a = 1 b = 2 | IndentationError: unindent does not match any outer indentation level | ||
TabError | Misturou Tab e espaços no recuo do mesmo bloco. | uma linha com Tab, a seguinte com 8 espaços | TabError: inconsistent use of tabs and spaces in indentation | Sintaxe e Indentação |
Arquivos, pastas e sistema (família OSError)
Todos estes são filhos de OSError ("erro do sistema operacional"). A mensagem traz um número entre colchetes, o Errno (número do erro no sistema), e o caminho do arquivo.
| Exceção | Quando acontece | Exemplo | Mensagem real | Aula |
|---|---|---|---|---|
FileNotFoundError | O arquivo (ou a pasta) não existe nesse caminho. | open("notas.txt") | FileNotFoundError: [Errno 2] No such file or directory: 'notas.txt' (no editor do guia: [Errno 44]) | Abrindo Arquivos |
PermissionError | Você não tem permissão para ler ou escrever ali. | open("segredo.txt") (depois de chmod 000 segredo.txt) | PermissionError: [Errno 13] Permission denied: 'segredo.txt' | Abrindo Arquivos |
IsADirectoryError | Tentou abrir uma pasta como se fosse arquivo. | open("/home/ana") | IsADirectoryError: [Errno 21] Is a directory: '/home/ana' | Pastas e Caminhos |
NotADirectoryError | Usou um arquivo como se fosse pasta no meio do caminho. | open("/etc/hostname/x") | NotADirectoryError: [Errno 20] Not a directory: '/etc/hostname/x' | Pastas e Caminhos |
FileExistsError | Tentou criar algo que já existe. | os.mkdir("/home/ana") | FileExistsError: [Errno 17] File exists: '/home/ana' | os e sys |
ProcessLookupError | Mandou um sinal para um processo que não existe. | os.kill(999999, 0) | ProcessLookupError: [Errno 3] No such process | subprocess |
ChildProcessError | Esperou por um processo filho, mas não há nenhum. | os.waitpid(-1, 0) | ChildProcessError: [Errno 10] No child processes | |
ConnectionRefusedError | O outro computador (ou programa) recusou a conexão: não há ninguém "atendendo" naquela porta. | socket.socket().connect(("127.0.0.1", 9)) | ConnectionRefusedError: [Errno 111] Connection refused | |
ConnectionResetError, ConnectionAbortedError, BrokenPipeError | A conexão caiu no meio da conversa (o outro lado fechou). | dependem da rede; todas são filhas de ConnectionError | ||
TimeoutError | Uma operação de sistema ou de rede esperou demais e desistiu. (Cuidado: o timeout= do subprocess.run lança outra exceção, a subprocess.TimeoutExpired.) | depende do tempo; sem mensagem fixa | ||
BlockingIOError, InterruptedError | Casos de programação de sistema (leitura sem espera, sinal no meio de uma chamada). Raros para quem está começando. | |||
IOError e EnvironmentError
Em programas antigos você pode ver except IOError. Hoje IOError e EnvironmentError são só outros nomes para OSError: no computador da Ana, print(EnvironmentError is OSError, IOError is OSError) mostrou True True. Em código novo, escreva OSError ou a filha exata.
Os outros erros
| Exceção | Quando acontece | Exemplo | Mensagem real | Aula |
|---|---|---|---|---|
ModuleNotFoundError | O módulo não existe ou não está instalado (ou o nome está errado). | import requets | ModuleNotFoundError: No module named 'requets' | pip |
ImportError | O módulo existe, mas não tem o nome que você pediu no from … import. | from math import raiz | ImportError: cannot import name 'raiz' from 'math' (unknown location) | Módulos e import |
RecursionError | Uma função chamou a si mesma vezes demais (quase sempre: faltou o caso de parada). | def f(): return f()f() | RecursionError: maximum recursion depth exceeded | Recursão |
RuntimeError | Erro "genérico" de execução. O caso clássico: mudar o tamanho de um dicionário enquanto passa por ele. | d = {1: 1}for k in d: d[2] = 2 | RuntimeError: dictionary changed size during iteration | Percorrendo um Dicionário |
NotImplementedError | Você mesmo lança, num método que as classes filhas ainda precisam escrever. | raise NotImplementedError | NotImplementedError | Herança |
StopIteration | next() num iterador que já acabou. O for usa esse sinal para saber quando parar (por isso você quase nunca o vê). | it = iter([])next(it) | StopIteration | Iteradores |
StopAsyncIteration | O mesmo, para iteradores assíncronos (async for). | raise StopAsyncIteration | StopAsyncIteration | asyncio |
AssertionError | Um assert deu falso. | assert 2 + 2 == 5 | AssertionError | Testes |
| Com mensagem depois da vírgula. | assert 1 > 2, "a nota não pode passar de 10" | AssertionError: a nota não pode passar de 10 | ||
EOFError | input() chegou ao fim da entrada sem ler nada (Ctrl-D, ou a entrada veio vazia de um arquivo). | input() com a entrada vazia | EOFError: EOF when reading a line | input() |
OverflowError | Uma conta com número decimal (float) passou do maior valor possível. Com int não acontece: inteiros crescem à vontade. | math.exp(1000)2.0 ** 10000 | OverflowError: math range errorOverflowError: (34, 'Numerical result out of range') (no editor do guia, o número é outro: (68, 'Result not representable')) | Números |
ValueError (número enorme) | Converter em texto (ou de texto) um inteiro com mais de 4300 algarismos: um limite de segurança. | int("9" * 5000) | ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 5000 digits; use sys.set_int_max_str_digits() to increase the limit | Números |
MemoryError | Pediu mais memória do que existe. | "a" * (2 ** 62) | MemoryError | |
UnicodeDecodeError | Leu bytes com a codificação errada (arquivo que não é UTF-8). | b"\xff".decode("utf-8") | UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte | Lendo Arquivos |
UnicodeEncodeError | Tentou gravar um caractere que a codificação escolhida não tem (o é não existe em ASCII). | "café".encode("ascii") | UnicodeEncodeError: 'ascii' codec can't encode character '\xe9' in position 3: ordinal not in range(128) | Escrevendo Arquivos |
LookupError | A mãe de IndexError e KeyError; sozinha, aparece com codificação desconhecida. | "a".encode("utf-99") | LookupError: unknown encoding: utf-99 | |
ReferenceError | Usou uma "referência fraca" (weakref) de um objeto que já foi apagado. | r = weakref.proxy(a)del ar.x | ReferenceError: weakly-referenced object no longer exists | |
ExceptionGroup | Vários erros juntos, de uma vez (usado com asyncio e tratado com except*). | raise ExceptionGroup("dois erros", [ValueError("a"), TypeError("b")]) | ExceptionGroup: dois erros (2 sub-exceptions) | asyncio |
PythonFinalizationError 3.13 | Algo tentou criar uma thread ou processo enquanto o Python está desligando. | raro; filha de RuntimeError | ||
SystemError, BufferError, FloatingPointError | Problemas internos do Python ou de módulos escritos em C. Se aparecer SystemError, é um defeito do Python, não do seu código. | |||
Um ExceptionGroup tem um traceback com cara própria, em forma de árvore, um ramo para cada erro do grupo:
$ python3 grupo.py
+ Exception Group Traceback (most recent call last):
| File "/home/ana/grupo.py", line 1, in <module>
| raise ExceptionGroup("dois erros", [ValueError("nota inválida"), KeyError("café")])
| ExceptionGroup: dois erros (2 sub-exceptions)
+-+---------------- 1 ----------------
| ValueError: nota inválida
+---------------- 2 ----------------
| KeyError: 'café'
+------------------------------------
Os pedidos para parar (fora de Exception)
| Exceção | Quando acontece | Exemplo | Mensagem real | Aula |
|---|---|---|---|---|
KeyboardInterrupt | Você apertou Ctrl+C com o programa rodando. | um while True: e Ctrl-C | KeyboardInterrupt | while |
SystemExit | O programa chamou sys.exit(). Não mostra traceback: o programa só termina, com o código que você deu. | sys.exit(3) | (nada na tela; echo $? mostra 3) | os e sys |
GeneratorExit | Um gerador foi fechado (close()) antes de terminar. É um sinal interno. | gerador.close() | (não aparece) | Geradores |
Avisos (Warning)
Os avisos são da família Warning: em vez de parar o programa, o Python escreve uma linha na saída de erros e continua. Eles servem para dizer "isso funciona, mas cuidado".
$ python3 -c 'import warnings; warnings.warn("cuidado com isso")'
<string>:1: UserWarning: cuidado com isso
| Aviso | Quer dizer |
|---|---|
UserWarning | O aviso padrão do warnings.warn(), para você usar nos seus programas. |
DeprecationWarning | "Isso vai sair numa versão futura do Python (ou da biblioteca); troque logo." |
PendingDeprecationWarning | "Isso vai ser marcado como ultrapassado mais adiante." |
FutureWarning | "O comportamento disto vai mudar." Comum em bibliotecas como pandas. |
SyntaxWarning | Código que roda, mas parece engano. Ex.: None() avisa 'NoneType' object is not callable; perhaps you missed a comma? já na leitura do arquivo. |
RuntimeWarning | Algo suspeito durante a execução (uma corrotina que ninguém esperou com await, por exemplo). |
ResourceWarning | Um arquivo ou conexão ficou aberto. Fica escondido por padrão; python3 -X dev mostra. Use with. |
EncodingWarning | open() sem encoding= (só aparece com -X warn_default_encoding). |
ImportWarning, UnicodeWarning, BytesWarning | Casos específicos de importação, Unicode e bytes; raros. |
Qual nome pôr no except
| Você quer tratar… | Escreva | Pega |
|---|---|---|
| texto que não vira número | except ValueError | int("dez"), float("1,5") |
| item ou chave que não existe | except LookupError (ou IndexError / KeyError) | listas, textos e dicionários |
| qualquer problema com arquivo | except OSError | não existe, sem permissão, é pasta… |
| só "arquivo não existe" | except FileNotFoundError | só esse |
| qualquer erro de conta | except ArithmeticError | divisão por zero, estouro |
| dois erros diferentes, mesmo tratamento | except (ValueError, ZeroDivisionError) | os dois |
| "qualquer erro", para registrar e seguir | except Exception as erro | todos, menos Ctrl-C e sys.exit() |
except com vírgula, sem parênteses 3.14
Até o 3.13, vários erros no mesmo except precisavam de parênteses: except (ValueError, TypeError):. No 3.14 os parênteses podem ficar de fora (PEP 758): except ValueError, TypeError: rodou no computador da Ana e pegou o ValueError. Se o seu programa também vai rodar num Python mais antigo (o Debian 13 traz o 3.13), continue usando os parênteses, que valem em todas as versões. Com as erro, os parênteses continuam obrigatórios: sem eles, o 3.14 recusa o arquivo com SyntaxError: multiple exception types must be parenthesized when using 'as'.
Experimente
Livre: cada linha da lista é um código que dá erro. O programa roda um por um e mostra a família de cada erro, da filha até a mãe. Acrescente os seus (por exemplo "[].pop()" ou "float('1,5')") e veja de que família eles são.
testes = [
"10 / 0",
"int('dez')",
"['pão', 'leite'][5]",
"{'pão': 4.5}['café']",
"'Idade: ' + 30",
"'ana'.upercase()",
"open('notas.txt')",
]
for codigo in testes:
try:
eval(codigo)
except Exception as erro:
familia = " → ".join(c.__name__ for c in type(erro).__mro__[:-1])
print(f"{codigo:24} {familia}")
No computador da Ana (com mais uma linha, import requets, rodada com exec), a saída foi:
$ python3 livre.py
10 / 0 ZeroDivisionError → ArithmeticError → Exception → BaseException
int('dez') ValueError → Exception → BaseException
['pão', 'leite'][5] IndexError → LookupError → Exception → BaseException
{'pão': 4.5}['café'] KeyError → LookupError → Exception → BaseException
'Idade: ' + 30 TypeError → Exception → BaseException
'ana'.upercase() AttributeError → Exception → BaseException
open('notas.txt') FileNotFoundError → OSError → Exception → BaseException
import requets ModuleNotFoundError → ImportError → Exception → BaseException
except com o nome errado
A Ana quis tratar o caso de alguém digitar a idade por extenso, mas pôs o nome errado no except:
texto = "dez"
try:
idade = int(texto)
print("Daqui a 1 ano:", idade + 1)
except ZeroDivisionError:
print("Não é um número:", texto)
$ python3 idade.py
Traceback (most recent call last):
File "/home/ana/idade.py", line 3, in <module>
idade = int(texto)
ValueError: invalid literal for int() with base 10: 'dez'
O except ZeroDivisionError só pega divisão por zero. O erro foi outro, ValueError, que não é filho de ZeroDivisionError: o except o deixou passar e o programa parou. A última linha do traceback diz qual nome usar.
Missão: conserte o programa da Ana: troque o nome no except pela exceção que o int("dez") realmente lança (leia a última linha do erro ao rodar). A saída deve ser Não é um número: dez.
texto = "dez"
try:
idade = int(texto)
print("Daqui a 1 ano:", idade + 1)
except ZeroDivisionError:
print("Não é um número:", texto)
texto = "dez"
try:
idade = int(texto)
print("Daqui a 1 ano:", idade + 1)
except ValueError:
print("Não é um número:", texto)
Resumo
- O nome da exceção está no começo da última linha do traceback:
NomeDaExceção: explicação. - As exceções formam uma árvore.
except Mãepega a mãe e todas as filhas:LookupErrorpegaIndexErroreKeyError;OSErrorpega os erros de arquivo;ArithmeticErrorpegaZeroDivisionError. KeyboardInterrupteSystemExitficam fora deException: por isso o "pega tudo" certo éexcept Exception, nuncaexcept:sozinho.TypeError= tipo errado;ValueError= tipo certo, valor ruim.SyntaxErroreIndentationErroraparecem antes de o programa rodar; umtryno mesmo arquivo não os pega.- Avisos (
Warning) não param o programa.