-2

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?

Roman
  • 1,396
  • 4
  • 15
  • 39
  • If you're worried about typos so much, make it a habit to use python3.6's typing checks inside an IDE. – cs95 Mar 11 '18 at 20:50
  • 2
    If you have a typo, your code will fail with a NameError or AttributeError, or some other easily diagnosed failure. A simple test would be enough to expose this. – Daniel Roseman Mar 11 '18 at 20:52
  • The problem it that python 3.6 is not always available. Now, assume that several team members prefer to use vim or something like that. And yes, as @DanielRoseman noted it will fail. The problem is that it might fail months after the code is written (suppose someone make changes which lead to regression). This, of cause, may be covered by automatic tests, but in real project you might be unable to provide 100% coverage. – Roman Mar 11 '18 at 20:52
  • 1
    The argument part of this is really a subjective question, but… In my experience, the kinds of type checks that you're planning to write assertions for aren't going to catch the errors you're actually going to make. All you get is the same false sense of security tha static typing in a relatively weak type system (like C++ or Java, as opposed to Rust or Haskell) gives you: your code compiles, but it's still chock full of reference/threading/etc. errors, and that's why you end up with more null pointer exceptions in Java than AttributeErrors on None in Python. – abarnert Mar 11 '18 at 20:56
  • Anyway, if Python 3.6 isn't available, why can't you use the backward-compatibility MyPy syntax, with type annotations either as comments or in typesheds? Sure, it's a bit ugly, but "I want to use Python 2.7 or 3.4 and it makes Python 3.6 features a bit ugly" is an argument to use Python 3.6, not an argument to hate those features. – abarnert Mar 11 '18 at 20:57
  • @abarnert, this, actually, looks quite like something I'm looking for. I've seen MyPy project, so I was wondering if there are other ways of type checking. And I'm looking forward for more of them) – Roman Mar 11 '18 at 21:00

1 Answers1

1

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).

abarnert
  • 354,177
  • 51
  • 601
  • 671