What does <py3fix> mean? - python

I am reading the bottle source code and see:
eval(compile('def _raise(*a): raise a[0], a[1], a[2]', '<py3fix>', 'exec'))
I read the documentation about compile and it only tells me that <string> is commonly used. I also googled and searched on stackoverflow but can not find the related info.
So can anyone tell me how <py3fix> affects compilation? And is there any other filename, where can I find the related documentation?
Thanks in advance.

It doesn't affect it at all. It's just a name that it's used to identify where the compiled code is coming from, so you can use string you want.
Like the docs say:
compile(source, filename, mode[, flags[, dont_inherit]])
The filename argument should give the file from which the code was
read; pass some recognizable value if it wasn’t read from a file
('< string>' is commonly used).
in the case where the source is not being read from a file (like here) they suggest that you use <string> so that you know that this code is compiled from a written string.
The person who comited the code, did it when fixing some Bottle Python 2/3 bugs. So I'm guessing that he used <py3fix> as a way to identify the assertion was raised from the def _raise he compiles when the user is running 2.x:
>>> eval(compile('def _raise(*a): raise a[0], a[1], a[2]', '<py3fix>', 'exec'))
>>> _raise(Exception, "error message", None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<py3fix>", line 1, in _raise
Exception: error message
>>> eval(compile('def _raise(*a): raise a[0], a[1], a[2]', '<my_source_file>', 'exec'))
>>> _raise(Exception, "error message", None)Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<my_source_file>", line 1, in _raise
Exception: error message

Related

Is it possible to edit the error template in Maya using python?

I'm currently learning how to code in python and I was trying to raise exceptions in my code to make my tool more user-friendly. However, I find the template given by Maya to be too simple and I'd like to have more control over it.
Normally, the base template looks a little like this:
raise Exception(errorTitle)
>>> Result
# Error: errorTitle
# Traceback (most recent call last):
# File "<maya console>", line 1, in <module>
# Exception: errorTitle #
It works fine, but it doesn't let you give a more detailed description of the error. What I'm trying to achieve would look a little more like this:
raise Exception(errorTitle, errorDescription)
>>> Result
# Error: errorTitle
# errorDescription
# Traceback (most recent call last):
# File "<maya console>", line 1, in <module>
# Exception: errorTitle #
I also tried putting the errorDescription into errorTitle by adding a new line to the string, but since errorTitle is repeated twice, it becomes confusing quickly when trying to sort errors.
I know you can't really use multiple arguments in the raise function, so I was wondering if there was an error template in Maya I could reference instead of raising an error.
Alternatively, is there a way to create my own error template? If I can reuse the Traceback function and change the script bar color, it might be easier to just do that.
Thanks in advance!
You can get your desired result just like that:
>>> raise Exception("Error Title\nError description that explains the problem")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: Error Title
Error description that explains the problem
Or you may want to declare your custom exception class:
class YourException(Exception):
def __init__(self, title, description):
super(YourException, self).__init__(title + "\n" + description)
and then you can use your original syntax:
>>> raise YourException("Error Title", "Error description that explains the problem")
File "<stdin>", line 1, in <module>
__main__.YourException: Error Title
Error description that explains the problem

How to catch python exception and save traceback text as string

I'm trying to write a nice error handler for my code, so that when it fails, the logs, traceback and other relevant info get emailed to me.
I can't figure out how to take an exception object and extract the traceback.
I find the traceback module pretty confusing, mostly because it doesn't deal with exceptions at all. It just fetches some global variables from somewhere, assuming that I want the most recent exception. But what if I don't? What if I want to ignore some exception in my error handler? (e.g. if I fail to send me email and want to retry.)
What I want
import traceback as tb
# some function that will fail after a few recursions
def myfunc(x):
assert x > 0, "oh no"
return myfunc(x-1)
try:
myfunc(3)
except Exception as e:
traceback_str = tb.something(e)
Note that tb.something takes e as an argument.
There's lots of questions on Stack Overflow about using the traceback module to get a traceback string. The unique thing about this question is how to get it from the caught exception, instead of global variables.
Result:
traceback_str contains the string:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in myfunc
File "<stdin>", line 3, in myfunc
File "<stdin>", line 3, in myfunc
File "<stdin>", line 2, in myfunc
AssertionError: oh no
Note that it contains not just the most recent function call, but the whole stack, and includes the "AssertionError" at the end
The correct function for tb.something(e) is
''.join(tb.format_exception(None, e, e.__traceback__))

What is wrong with my python movie database code?

I was looking for some help with a program I am writing for personal use. It is supposed to export a movie's name and rating (stored in a dictionary) to an external file (file.txt) and then load it at the start of every run. It should also export a movie's name and review (also a dictionary) to another external file (review.txt). I get an error on the line for reading the file.txt and putting it in base. Any clues?
base = {}
#Open and write info to base
with open('file.txt','r') as f:
# Error here :(
base = eval(f.read())
error message:
Traceback (most recent call last):
File "/Users/Will/Documents/movie_database.py", line 18, in <module>
base = eval(f.read())
File "<string>", line 0
^
SyntaxError: unexpected EOF while parsing
Your file is empty, so eval() throws an exception because no Python expression was found:
>>> eval('') # empty string
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 0
^
SyntaxError: unexpected EOF while parsing
You shouldn't be using eval() in the first place however, the security implications are terrifying here. Someone that can fool you into loading an arbitrary file can now take over your Python process, and turn your machine into a spam bot zombie.
json or shelve (or directly using pickle, although that has security implications as well) would offer you better and more robust serialisation options. You could also look into using sqlite3 for a SQL database option.

What's the use of the filename parameter of ast.parse?

The documentation reads:
ast.parse(source, filename='<unknown>', mode='exec')
Equivalent to compile(source, filename, mode, ast.PyCF_ONLY_AST).
compile(source, filename, mode[, flags[, dont_inherit]])
The filename argument should give the file from which the code was read;
pass some recognizable value if it wasn’t read from a file
('<string>' is commonly used).
But it doesn't tell me much how to get this filename back from the AST node. Or how is this filename parameter is used. Is it just a stub?
It sets the co_filename attribute on the code object, which is used to display the filename in tracebacks. Besides that, it's not really significant what value you pass.
>>> c = compile('raise Exception("spam")', 'eggs', 'exec')
>>> eval(c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "eggs", line 1, in <module>
Exception: spam

Why do I get IOErrors when writing Unicode to the CMD? (With codepage 65001)

I'm on the CMD in Windows 8 and I've set the codepage to 65001 (chcp 65001). I'm using Python 2.7.2 (ActivePython 2.7.2.5) and I've set the PYTHONSTARTUP environment variable to "bootstrap.py".
bootstrap.py:
import codecs
codecs.register(
lambda name: name == 'cp65001' and codecs.lookup('UTF-8') or None
)
This lets me print ASCII:
>>> print 'hello'
hello
>>> print u'hello'
hello
But the errors I get when I try to print a Unicode string with non-ASCII characters makes no sense to me. Here I try to print a few strings containing Nordic symbols (I added the extra line break between the prints for readability):
>>> print u'æøå'
��øåTraceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory
>>> print u'åndalsnes'
��ndalsnes
>>> print u'åndalsnesæ'
��ndalsnesæTraceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument
>>> print u'Øst'
��st
>>> print u'uØst'
uØstTraceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument
>>> print u'ØstÆØÅæøå'
��stÆØÅæøåTraceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument
>>> print u'_ØstÆØÅæøå'
_ØstÆØÅæøåTraceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 22] Invalid argument
As you see it doesn't always raise an error (and doesn't even raise the same error every time), and the Nordic symbols is only displayed correctly occasionally.
Can somebody explain this behavior, or at least help me figure out how to print Unicode to the CMD correctly?
Try This :
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
print u'æøå'
Making use of from __future__ import unicode_literals would be useful in an interactive python session.
It is certainly possible to write Unicode to the console successfully using WriteConsoleW. This works regardless of the console code page, including 65001. The code here does so (it's for Python 2.x, but you'd be calling WriteConsoleW from C anyway).
WriteConsoleW has one bug that I know of, which is that it fails when writing more than 26608 characters at once. That's easy to work around by limiting the amount of data passed in a single call.
Fonts are not Python's problem, but encoding is. It doesn't make sense to fail to output the right characters just because some users might not have selected fonts that can display those characters. This bug should be reopened.
(For completeness, it is possible to display Unicode on the console using fonts other than Lucida Console and Consolas, but it requires a registry hack.)
I hope it helps.

Categories

Resources