Python3: How to define exceptions in method headers? - python

yesterday, I found a way to simulate something like type-safety in python 3 (and maybe in python 2 ;). For example by writing the following:
def do_stuff(amount: int, name: str, place: str = 'London') -> list:
you can tell your IDE to notify you if you want to set an argument which has not the expected type (giving a string where you would expect an integer). Python itself ignores them, which is totally fine for me.
However, now I want to provide it with exceptions which may be thrown during the process. How can I achieve this? Unfortunately, I don't even know what to search for. Can someone help me out? I want my IDE (PyCharm) to remind me, that in some cases the function I'm using may throw an exception and it would be a nice idea to wrap it in a try-except statement.
I'm only talking about methods written by myself, not external code and it's for documentation only. Unfortunately reStructuredText or epytext do document this, but don't help with the IDE-checks =Y
Thanks in advance
Kenneth

This does not appear to be supported. The proposal that added type hinting, PEP484, says this about exceptions:
No syntax for listing explicitly raised exceptions is proposed. Currently the only known use case for this feature is documentational, in which case the recommendation is to put this information in a docstring.

Related

Pythonic way vs common sense. Type checking

I've seen a number of questions like following one: What's the canonical way to check for type in Python?
And there's always someone answering something like: "The pythonic way of checking types is not checking them. and here goes another passage about duck typing."
First of all, I do understand pros of duck typing, and I do use it quite a lot. But is it really worth not to check types?
Suppose I have following code:
class DuckA:
def quack():
print("QuackA")
class DuckB:
def quack():
print("QuackB")
def duck_creator():
return DuckA()
def duck_client(duck):
duck.quack()
if __name__ is "__main__":
duck_client(DuckA()) #ok
duck_client(DuckB()) #ok
duck_client(duck_creator()) #ok
#totally fine untill you actually call it,
#which might be quite tricky to check in
#relatively big project
duck_client(duck_creator)
#one more typo, which is pretty hard to spot
#from first sight
duck_client(DuckB)
Yes, I do realize that we're all engineers and thus, we're supported to write adequate constructions, but what about all kinds of typos?
I'm a beginner in python, and I came from c/c++ crowd. Basically, all those answers involving duck typing sound to me somewhat like "if you don't want to spend hours in debugger, you just need to write code without errors".
So, python gurus, is there are any valid/pythonic/accepted techniques to overcome things like that?
I've seen all kinds of type checkers, which are good enough, although I don't like the idea of binding project to one of those ides.
Assertions in the beginning of the function do look quite promising from my point of view.
Any other ideas?
I think what you're looking for is Mypy, a static type checker for Python 2.7+/3.4+. It's the type checker that Python 3.6's annotation system is designed around, but they've been careful to make sure it can be used with older versions of Python. (In fact, part of the motivation for type hints in the first place is that Guido wanted to use Mypy to help guide upgrading a large codebase from 2.7 to 3.5.)
Of course you can't use 3.6 syntax in older versions of Python. In 3.5, parameters can be annotated, but not locals. In 3.4, annotations are limited. In 2.7, annotations don't exist at all.
If you read the docs, there are a few ways around this, but the basic idea is that you put all the annotations into comments in "public" code, while you write "typeshed" files full of out-of-line annotations for "internal" code.
The good news is that, because Mypy has been blessed by the core language, other static type checkers—and related tools like IDE indexers or deeper static analyzers—are adapting to do things the same way, so whatever you use for your 2.7 or 3.4 code is probably going to work with your favorite IDE or vim plugin or analyzer or whatever (if not today, then soon).

Using exception handler to extend the functionality of default methods (Python taken as example)

So, I'm new to programming and my question is:
Is it considered a bad practice to use an exception handler to override error-message-behaviour of default methods of a programming language with custom functionality? I mean, is it ethically correct to use something like this (Python):
def index(p, val):
try:
return p.index(val)
except ValueError:
return -1
Maybe I wasn't precise enough. What I meant is: is it a normal or not-recommended practice to consider thrown exceptions (well, I guess it's not applicable everywhere) as legit and valid case-statements?
Like, the idea of the example given above is not to make a custom error message, but to suppress possible errors happening without warning neither users nor other program modules, that something is going wrong.
I think that doing something like this is OK as long as you use function names which make it clear that the user isn't using a built-in. If the user thinks they're using a builtin and all of a sudden index returns -1, imagine the bugs that could happen ... They do:
a[index(a,'foo')]
and all of a sudden they get the last element in the list (which isn't foo).
As a very important rule though, Only handle exceptions that you know what to do with. Your example above does this nicely. Kudos.
This is perfectly fine but depends on what kind of condition you are checking. It is the developers responsibility to check for these conditions. Some exceptions are fatal for the program and some may not. All depends on the context of the method.
With a language like python, I would argue it is much better to give a custom error message for the function than the generic ValueError exception.
However, for your own applications, having this functionality inside your methods can make code easier to read and maintain.
For other languages, the same is true, but you should try and make sure that you don't mimick another function with a different behaviour, whilst hiding the Exceptions.
If you know where exactly your errors will occur and the cause of error too, then there is nothing wrong with such kind of handling. Becaues you are just taking appropriate action for something wrong happening, that you know can happen .
So, For E.g: - If you are trying to divide two numbers, and you know that if the denominator is 0, then you can't divide, then in that case you can use a custom message to denote the problem.

How to deal with wrong parameters types in dynamic-languages?

I can't find the answer on SO but it's very likely that the argument has been already discussed.
I'm trying to write a quite small size program using the Python language. It's my first "real" experience with a dynamic language and I would prefer to do everything in the right way. One of the practice that I would try to apply since the beginning is unit-testing.
How can I quickly test that the parameters of a method are of the right type? Should I do it?
With right type I mean for instance to check that a method that works with float numbers is not called with a String. In this case consider the possibility that the method should obviously accept even integers and not only float.
How can I quickly test that the parameters of a method are of the right type?
The quickest way is to do nothing.
Seriously. The dynamic language interpreter (Python in this case) will check far more quickly than any code you could ever write. It will simply raise an exception and that's all you need to do. Nothing.
Should I do it?
Never test for the right type. You can't -- in general -- do it.
Let's say you have a function that requires a "number"
def some_func( x ):
assert isinstance(x, int)
Bad policy. Your function may work for long or float just as well as int.
assert instance( x, (int, long, float) )
Bad policy. You've still excluded complex. Indeed, you've also excluded decimal.Decimal and fractions.Rational which are also valid numbers.
By "type checking" you're going to exclude valid types. The only thing you can do is assume the types are proper and handle the exception gracefully when someone "misuses" your function or class and provides wrong types.
The most graceful way to handle TypeError?
Do nothing. The program should totally crash.
You shouldn't test for specific types. According to the docs, you should simply use the passed-in object as needed and give the user the opportunity to supply a custom implementation.
Depending on what your function does, it may be appropriate to convert the arguments to the expected type:
def my_func(a):
a = float(a)
# ...do stuff...
Another excellent option is to use hasattr() to check for the desired member before using it. That would let you throw a helpful exception, instead of the default AttributeError.
Unit testing with complete coverage is really the only way to handle any development work which relies on dynamic languages. Clearly it's very beneficial to have strong coverage tests for statically typed languages but in my experience it's even more important when you have dynamic typing.
If you aren't covering all the code that can run in your tests, then really you are asking for trouble. So you want to use a coverage analysis tool in tandem with your unit tests to prove that you are reaching all of your code.
Even that won't guard against all pitfalls – your tests really need to exercise all the possibly erroneous input data errors your program may receive.

Is there a good language/syntax for field validation we can re-use?

I'm working on a web app (using Python & Bottle) and building a decorator for validating HTTP parameters sent in GET or POST. The early version takes callables, so this:
#params(user_id=int, user_name=unicode)
... ensures that user_id is an int, user_name is a string, and both fields exist.
But that's not enough. I want to be able to specify that user_name is optional, or that it must be non-empty and within 40 characters. Implementing that is easy enough, but I'm struggling with what syntax would be most elegant. It seems like that might be a problem someone's solved before, but I'm not finding an answer. Specifically I'm wondering if there's an elegant way to take parseable strings that provide the syntax. Something like:
#params(user_id='int:min1', user_name='unicode:required:max40')
I just don't want to invent a syntax if there's a good one floating around somewhere.
Anyone seen something like this? In any language..but I'm specifically valuing terseness and readability.
You could use lists.
#validate(user_id=[int, min(1)], user_name=[unicode,required,max(40)])
And each item could be a function (or class/object) that gets executed with the corresponding field as an argument. If it raises an error, it fails validation.

Python Strongly type lists

I am using eclipse for python and I am facing a problem. I have many classes with many properties and want a list of objects from one of my declared classes. The problem is: When I am accessing any item from the list, the IDE does not know its type because in python we do not declare the variable with type, so there is no auto complete and I have to go to the class to copy the attribute name.
To make idea more clear:
class AutomataBranch(object):
def __init__(selfparams):
self.Name="";
self.nodes=[];
class LanguageAutomata(object):
def __init__(selfparams):
self.cfgAutomata=[];#This has AutomaBranch Type
Now in any method in LanguageAutomata class if I wrote:
cfgAutomata. Then it wont give me the Name attribute
Is there any solution for that?
Python is strongly typed and Python lists are too. Your problem come from the fact that Python is dynamically typed. Therefor a var can contain any type, and therefor no IDE can guess what is the type of your parameter, nor give you code completion for the methods.
This is how it is, there is no clean workaround. If it's a problem, then maybe dynamics language is not you predilection tool and you should use something that fit your development style. There are tools for everybody.
8 years later and we actually have a solution in Python 3.6.
PEP484 allows you to annotate your variables primarily for IDEs and linting:
Modifying #Hani's answer:
x : AutomataBranch = self.cfgAutomata[i]
This is now picked up by any good IDE to highlight errors and allow autocomplete.
I think you mean to say "statically typed" instead of "strongly typed." Python is strongly typed. You just don't know what that type is at compile time.
With that said, you really need to abandon the idea that you're going to find any IDEs that work as well for Python as they do for Java or C#. Python's dynamic typing makes this difficult. In fact, I tend to find that powerful IDEs are more of a burden than a help.
I think I found a good managable solution. Actually it is trivial but may help (I used it now).
When I want to access the list then I assign the object which I want to access to a variable ex:
x = AutomataBranch()
x = self.cfgAutomata[i]
The first line is used only to make the IDE knows that x is from AutomatBranch type. After that when I press x then all methods and properties are visualized.
I think it is some how good.

Categories