0

I was looking through https://github.com/python/cpython/blob/master/Lib/datetime.py and stumbled across some type checking functions (I simplified them, original is _check_int_field)

def foo(year, month, day): year = check_int(year) month = check_int(month) day = check_int(day) 

check_int returns the value inputted (if it's an integer) - and raises ValueError if it's not. Let me shorten the function they used:

def check_int(value): if isinstance(value, int): return value if not isinstance(value, int): raise TypeError('integer argument expected, got %s' % type(value)) 

My question is: What's the meaning behind the return statement? Surely you could just have it implemented as

def check_int(value): if not isinstance(value, int): raise TypeError('integer argument expected, got %s' % value) 

This would change the foo function to (where you wouldn't have to define the variables, but simply use the foo arguments)

def foo(year, month, day): check_int(year) check_int(month) check_int(day) 

This would raise an TypeError if the input type is wrong - and simply keep on going with the function arguments if not, without having to define any variables. So why do they return the input variable, if they dont modify it, but simply check it?

6
  • 1
    Do you mean _check_int_field? Because in some cases it does return something other than just its argument. Your "simplification" is profoundly unhelpful; your posted version could be replaced, because it's not representative of the real thing. Commented Oct 12, 2019 at 15:48
  • Yes, but it only returns value, value.__index__() or value.__name()__, which shouldn't really change the variable - it's gonna be the same integer regardless. What functionality does index__() and __name() provide, that would require the return statement? Commented Oct 12, 2019 at 15:52
  • as @rdas pointed out here you left out a pretty important section of the code, mainly being the try block. This has the potential to change the value of value. if it was a simple type check you could use assert isinstance(value, int), "Type of %s should be int"%s rather than defining functions for this at all. Commented Oct 12, 2019 at 15:53
  • If the function returns a value and you don't want it, you are free to ignore it. If the function does not return a value but you need it, well, you're out of luck. The return simply makes it more general. Consider a call like check_int(x + 3); if its valid, you don't have a reference to what is valid, and you need to compute it again. Commented Oct 12, 2019 at 15:53
  • What do you mean "shouldn't really change the variable"? How does returning an attribute of the parameter instead of the parameter itself not change the variable?! Commented Oct 12, 2019 at 15:53

1 Answer 1

1

In general I agree that pure validation functions may as well be void i.e. return nothing and raise an exception if required.

However, in this particular case, the _check_int_field function is actually used like this:

year = _check_int_field(year) 

And this makes sense because in the _check_int_field they do this:

try: value = value.__int__() except AttributeError: pass else: if not isinstance(value, int): raise TypeError('__int__ returned non-int (type %s)' % type(value).__name__) return value 

So the function is actually doing more than just validation. In which case, it makes sense for the function to return the value.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the clarification! It was (kind of) was I was expecting - I simply just don't quite understand the purpose of int and index, which led to my confusion

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.