refextract importing issues: syntax error - python

Does anyone have any experience using the python library Refextract, package index here. I'm using python 3.4 in Spyder 3.0.0. Pip install went fine, it said the installation was succesfull, in the correct folder (in the Libs/Site packages/ folder). But when I try to load it, it throws in a error message, and I can't really figure out what it means.
Here is my code snippet: from refextract import extract_journal_reference (as displayed in the manual), which gives the following error:
from refextract import extract_journal_reference
File "C:\path\to\python-3.4.3.amd64\lib\site-packages\refextract\references\api.py", line 96
raise FullTextNotAvailableError("URL not found: '{0}'".format(url)), None, sys.exc_info()[2]
^
SyntaxError: invalid syntax
This is just the importing, not yet the specifying of the link. Does anyone know what to do with this error?

The code that raises the exception is using syntax which is valid in Python2, but not in Python3.
In Python2, it is possible to associate an arbitrary traceback with an exception with this variation of the raise statement.
raise FooError, 'A foo has happened', a_traceback_object
or as in this case:
raise FooError('A foo has happened'), None, a_traceback_object.
In Python3, the traceback object must be explicitly assigned to the exception's __traceback__ attribute:
ex = FooError('A foo has happened')
ex.__traceback__ = a_traceback_object
raise ex
See PEP 3109 for discussion of this change (summary: reduce the number of different ways of using raise).
As far as I can see, the package does not claim to be python3-compliant, so you need to run it with Python2 (specifically, 2.7).

Related

Formatting Python exception?

I'm importing some Python modules and they will raise exception with calls like raise TypeError(xyz). And now I want to change the line number of the reported exceptions if there is any.
I couldn't find the right solution on the site for my case, the one I found all required the raise() to be in a try and except block. With the warnings module I can do warnings.formatwarning to customize its format. Can I do the same with exception?

pylint disabling a single line of code just produces another pylint error

The documentation in section 4.1 clearly states:
https://pylint.readthedocs.io/en/latest/faq.html#message-control
4.1 Is it possible to locally disable a particular message?
Yes, this feature has been added in Pylint 0.11. This may be done by adding “#pylint: disable=some-message,another-one” at the desired block level or at the end of the desired line of code
Great! but it doesn't work. Boo.
I get the the following pylint error for the following line of code
W: 26, 2: Redefining built-in 'zip' (redefined-builtin)
try:
from itertools import izip as zip # pylint: disable=bad-builtin
except ImportError:
pass
But pylint just complains even louder about my attempt to shut it up:
E: 26, 0: Bad option value 'bad-builtin' (bad-option-value)
I've also tried the error code # pylint: disable=W0141, that also produces a similar error.
Any idea what I'm doing wrong?
I have been in a similar situation.
Unsolvable pylint issue
class A:
pass
There are many warnings in pylint for the code above, but I want to talk about old-style-class.
In Python 2.7, you will get an old-style-class error.
Of course, you can change your code like this:
class A(object):
pass
However, you will receive a useless-object-inheritance warning in Python 3.
If you are writing a package compatible with python 2.7 and 3 and using pylint, then you are down.
Unavoidable bad-option-value
Yes, if it is accepted to disable either of old-style-class or useless-object-inheritance in a comment, you can go further.
In Python 2.7:
# pylint: disable=old-style-class
class A:
pass
In Python 3:
# pylint: disable=useless-object-inheritance
class A(object):
pass
Eventually, you will get a bad-option-value, just the same as this question.
Disable bad-option-value
I have tried, but bad-option-value can not be disabled locally in this case.
I have to disable bad-option-value in a pylint configuration file, like .pylintrc.
[TYPECHECK]
disable=bad-option-value
Note: My pylint version is 1.9.4 in python 2.7, 2.2.2 in python 3.
Ah, simple answer, it should be # pylint: disable=bad-option-value which is presented in the error message in parenthesis:
E: 26, 0: Bad option value 'bad-builtin' (bad-option-value)
When you get this message:
W: 26, 2: Redefining built-in 'zip' (redefined-builtin)
You have to disable the exact error message you are getting (the one in parenthesis):
try:
from itertools import izip as zip # pylint: disable=redefined-builtin
except ImportError:
pass
That seems to work fine in pylint 2.5.
It can be annoying if you are testing with multiple versions of python or different venvs and the same code base and you get different errors. Be sure you fix the version to one version across all your builds/tests. It sounds like that may have happened here (not sure where you got bad-builtin from).

Are Python Exceptions (apart from SyntaxError) runtime errors?

If I understand correctly, when I run a Python program, the Python interpreter generates bytecode (the .pyc file that appears alongside the .py source) unless the source contains a syntax error.
Does the bytecode compiler generate any other exceptions or are all the other exceptions raised at runtime when the .pyc code is being executed?
Well, any exception type can technically be raised during runtime via raise <exception>. But I assume that you understand this and are asking what exceptions might be raised while Python interprets your code (before execution). There are actually quite a few:
SyntaxError: This is raised by the parser as it reads the code. It results from invalid syntax such as unbalanced parenthesis, using a keyword in the wrong place, etc.
IndentationError: This is a subclass of SyntaxError and is raised whenever your code has improper indentation. An example would be:
if condition:
line_indented_4_spaces
line_indented_3_spaces
TabError: This is a subclass of IndentationError and is raised when you inconsistently mix tabs and spaces in a source file.
SystemError: This is raised by the interpreter when an internal operation fails. Encountering one usually means that your Python installation is messed up and might need a reinstall.
MemoryError: This is similar to SystemError and can be raised when an internal operation fails for lack of memory.
All of these exceptions can be raised before your code even begins to execute. The first three are caused by a corrupt source file and can be resolved by simply fixing the syntax or indentation. The latter two however are raised by the interpreter itself for internal operations which fail. This means that they are rare, but also that they are more serious and not so easy to fix.
There is no compilation step typically when you're working with Python code so I would argue that all errors in Python, SyntaxErrors included, are runtime errors.
For example, lets write this file:
in xrange(5):
That's obviously just nonsense (we'll even name it nonsense.py), but lets fire up the interpreter:
$ python
>>> try:
... import nonsense
... except SyntaxError:
... print("A syntax error occurred at runtime!")
...
A syntax error occurred at runtime!
>>>
So there you have it - a SyntaxError was raised and caught at runtime, which, in my mind at least, indicates that it's a runtime error.

How to find out where a Python Warning is from

I'm still kinda new with Python, using Pandas, and I've got some issues debugging my Python script.
I've got the following warning message :
[...]\pandas\core\index.py:756: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
return self._engine.get_loc(key)
And can't find where it's from.
After some research, I tried to do that in the Pandas lib file (index.py):
try:
return self._engine.get_loc(key)
except UnicodeWarning:
warnings.warn('Oh Non', stacklevel=2)
But that didn't change anything about the warning message.
You can filter the warnings to raise which will enable you to debug (e.g. using pdb):
import warnings
warnings.filterwarnings('error')
*The warnings filter can be managed more finely (which is probably more appropriate) e.g.:
warnings.filterwarnings('error', category=UnicodeWarning)
warnings.filterwarnings('error', message='*equal comparison failed*')
Multiple filters will be looked up sequentially. ("Entries closer to the front of the list override entries later in the list, if both match a particular warning.")
You can also use the commandline to control the warnings:
python -W error::UnicodeWarning your_code.py
From the man page:
-W argument
[...] error to raise an exception instead of printing a warning message.
This will have the same effect as putting the following in your code:
import warnings
warnings.filterwarnings('error', category=UnicodeWarning)
As was already said in Andy's answer.
The most informative way to investigate a warning is to convert it into an error (Exception) so you can see its full stacktrace:
import warnings
warnings.simplefilter("error")
See warnings.
If you enable logging in python, then when an exception is received you can use the method logging.exception to log when an exception has been caught - this method will print out a nicely formatted stack trace that shows you exactly in the code where the exception originated. See the python document on logging for more information.
import logging
log = logging.getLogger('my.module.logger')
try:
return self._engine.get_loc(key)
except UnicodeWarning:
log.exception('A log message of your choosing')
Alternatively, you can get a tuple that contains details of the exception in your code by calling sys.exc_info() (this requires you to import the sys module).

Which Python exception should I throw?

I'm writing some code to manipulate the Windows clipboard. The first thing I do is to try and open the clipboard with OpenClipboard() function from the Windows API:
if OpenClipboard(None):
# Access the clipboard here
else:
# Handle failure
This function can fail. So if it does, I would like to raise an exception. My question is, which of the standard Python exceptions should I raise? I'm thinking WindowsError would be the right one, but not sure. Could someone please give me a suggestion?
It is better to avoid raising standard exceptions directly. Create your own exception class, inherit it from the most appropriate one (WindowsError is ok) and raise it. This way you'll avoid confusion between your own errors and system errors.
Raise the windows error and give it some extra infomation, for example
raise WindowsError("Clipboard can't be opened")
Then when its being debugged they can tell what your windows error means rather than just a random windowserror over nothing.
WindowsError seems a reasonable choice, and it will record extra error information for you. From the docs:
exception WindowsError
Raised when a Windows-specific error occurs or when the error number does not correspond to an errno value. The winerror and strerror values are created from the return values of the GetLastError() and FormatMessage() functions from the Windows Platform API. The errno value maps the winerror value to corresponding errno.h values. ...

Categories