Getting Python assertRaises to check for message - python

I want to use assertRaises and check for the error message too. According to the docs I have to use it as a context manager.
with self.assertRaises(ValueError, msg='Invalid id format.'):
api.get_by_id('a')
This results in the following error:
TypeError: assertRaises() missing 1 required positional argument: 'callableObj'
I get the exact same error if I use it without msg.
Using it like assertRaises(exception, callable, *args, **kwds) works fine, but that obviously can't process the error message.
I don't understand why Python can't recognise the use case I'm going for.
Python 3.7.10, MacOS Monterey 12.2

Two things - first of all, it's hard to tell what actually happens but there must be some other error in your code because
with self.assertRaises(ValueError, msg='Invalid id format.'): should work perfectly fine (tested on Python 3.10)
2nd thing - msg argument does not do what you want it to do - self.assertRaises as a context manager with msg argument not working as expected
Link provided also explains how to check for error message with assertRaisesRegex

Related

stat() got an unexpected keyword argument 'follow_symlinks'

Web search found links to bugs, I don't write complicated code on Python, just want to confirm I understand syntax:
https://docs.python.org/3/library/pathlib.html
Path.stat(*, follow_symlinks=True)ΒΆ
But when I write Path(filepath).stat(follow_symlinks=False) I'm getting "stat() got an unexpected keyword argument 'follow_symlinks'" error. lstat() in place of stat(follow_symlinks=False) does job done.
Python 3.8.5. TIA
You're reading it correctly. You just missed the footnote. From the page you linked
Changed in version 3.10: The follow_symlinks parameter was added.
So if you want to use that keyword argument, you need Python 3.10 or newer. Otherwise, as you've already figured out, just use lstat.

GRPC Error: Parameter to MergeFrom() must be instance of same class

I have seen all previous questions about this, but nothing seems to be working on my end. I am trying to run a test that uses a protobuf generated file, called 'resource_pb2'. I am using Python 3.8 with grpc 1.33.2 and protobuf version 3.14.
When using a class from this protobuf generated file, my test fails with the following error:
Parameter to MergeFrom() must be instance of same class: expected RecognitionResource got RecognitionResource
I've checked the type and id's of all the "recognition resource" classes being called in that particular test, and I get the following:
<class 'resource_pb2.RecognitionResource'> 2069160783760
<class 'resource_pb2.RecognitionResource'> 2069160783760
<class 'resource_pb2.RecognitionResource'> 2069160783760
They are clearly all being called from the same source, so why is this issue occuring?
I had a similar issue and the reason was that I had made a mistake when passing parameters to the function.
The problem was solved when I realized about my bug and I invoked the function in the right way, with all required parameters properly set.
Hope it helps.

Is there a python linter that checks types according to type hints?

I'm looking for a Python linter, that can check types usage according to the type hints in the code.
The purpose is to run a single check that verifies style, logic, and type errors.
I need to run this on CI server, and as a file watcher during development.
For example, I need this code to output an error for passing the wrong type argument -
def double(x: int):
return x * 2
result = double('hello')
I've checked the documentation of PyLint and flake8, and couldn't find any support for type checking.
With PyLint I also verified there are no errors when checking the above code.
Yes, there is, it's called mypy

PyQt5 create error upon failed dbus request

Using PyQt5's D-Bus, how do I create an error? For example, if someone sends an unknown command in a chat program, I'd like to be able to let the client know something like as follows:
error = QDBusMessage.createError(QDBusError.UnknownProperty, "unknown command")
QDBusConnection.systemBus().send(error)
However, this fails with the message:
*** TypeError: arguments did not match any overloaded call:
createErrorReply(self, str, str): first argument of unbound method must have type 'QDBusMessage'
createErrorReply(self, QDBusError): first argument of unbound method must have type 'QDBusMessage'
createErrorReply(self, QDBusError.ErrorType, str): first argument of unbound method must have type 'QDBusMessage'
I can't make heads no tail of this error, since as far as I can tell I'm using it exactly as described. The first arg must be QDBusMessage, since that's what's before the dot. The second arg is of the right type, being <class 'PyQt5.QtDBus.QDBusError.ErrorType'> as returned by type(QDBusError.UnknownProperty). And the quotes mean it's a string, which is what str is.
I also tried sendErrorReply(), but that doesn't seem to exist in PyQt5. At least, I can't find it - it's not beside systemBus's send(), and it's not found in QDBusMessage.
Neither of the examples in PyQt5's examples/dbus/chat folder emit errors. There is no Python documentation available at http://pyqt.sourceforge.net/Docs/PyQt5/QtDBus.html.
I came across your question when I had the same problem as you, a lack of sendErrorReply in PyQt5.
Here's how I got it to work in my Bluetooth application:
#pyqtSlot(QDBusMessage)
def AuthorizeService(self, message):
print("rejecting service authorization")
error = message.createErrorReply(QDBusError.AccessDenied, "Failed")
self._bus.send(error)
The trick is to create the error reply from the message that was received.

Check for parameter TypeError without executing it

About the following code, how can I know the TypeError before execute it? is it possible?
My p.py script:
class X:
def __init__(self, **kwargs):
pass
x = X(1)
When I compile it, it raises no errors:
LM-SHC-00950567:test$ python -m py_compile p.py
LM-SHC-00950567:test$ python -m compileall p.py
But when I execute it, it does:
LM-SHC-00950567:test$ python p.py
Traceback (most recent call last):
File "p.py", line 7, in <module>
x = X(1)
TypeError: __init__() takes 1 positional argument but 2 were given
how can I know the TypeError before execute it? is it possible?
With python only, no, you can't. Python is a dynamic language, not a static one. It doesn't perform any checks to see whether you have errors before you execute, it just executes. It's your fault if you make a conceptual error like you did.
What you can do of course, is use a static checking tool for this. One candidate which has gotten attention recently due to type hints, is mypy , a static checker that, among other cool things, catches these sort of errors.
Running mypy on your script yields:
(Python3)jim#jim: mypy p.py
p.py:6: error: Too many arguments for "X"
So it caught it without requiring execution.
In general though performing checks like these is not what python is about. In python we try first and catch exceptions later (EAFP principle). For example, if your p.py script had a line of the form print(X.i), which is an obvious AttributeError, instead of checking it it would be better to wrap it in a try-except:
try:
print(X.i)
except AttributeError:
print("X has no attribute i")
it's possible if you know the language construct:
for example in python if you use **kwargs python expects you to call that class with keyword arguments while creating objects of that class e.g x = X(value = 25) your above code would've worked if you used def __init__(self, *args) which takes positional arguments(an arbitrary number of arguments), so that's it, hope it helps.

Categories