Approaches to argument type-checking
Hi all,
I am currently looking at issue 5236. This issue regards the exception
raised when a bytes string is passed into time.strptime. In addition to the
specific question I have regarding this issue, I wasn't sure if this was
something for python-dev or for the issue comment. However, it does concern
general Python coding approach, so just give me a pointer over whether this
is better kept on the tracker or whether posting to the list was a good idea
(I'm slowly learning!)
EXAMPLE OF PROBLEM:
>>> time.strptime(b'2009', "%Y")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/tjl/python3/lib/python3.1/_strptime.py", line 454, in
_strptime_time
return _strptime(data_string, format)[0]
File "/home/tjl/python3/lib/python3.1/_strptime.py", line 322, in
_strptime
found = format_regex.match(data_string)
TypeError: can't use a string pattern on a bytes-like object
WHEREAS:
>>> time.strftime(b"%Y")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: strftime() argument 1 must be str, not bytes
What is occurring here is that the arguments to strftime are being
type-checked up-front, whereas in strptime they are not. Further, srtptime
is implemented in a python file, _strptime.py, whiel strftime is implemented
in timemodule.c.
It appears as though it is generally the case (or at least often the case)
that C functions are making use of the vgetargs function which performs a
goodly bit of type checking. However, the same does not seem to hold for the
Python interface functions.
>From the Python interpreter perspective, though, both are in the time module
(time.strftime and time.strptime) so the inconsistency is a bit jarring. I
can see that I could solve this a few ways:
* Do a false-parse of the arguments using the same vgetargs1 method, but
not do anything with the return value
* Perform a type-check on the relevant argument, data_string, in Python
and raise a more specific Exception
* Write some kind of generic type-checking helper method which could be
re-used
Is there a general strategy used in Python development which I should be
aware of? i.e. is it customary to type-check every argument of an interface
method? Or is it customary not to perform type checking up-front and simply
allow the exception to occur deeper in the code? Are there performance
issues surrounding defensive programming?
Regards,
-Tennessee
--
--------------------------------------------------
Tennessee Leeuwenburg
http://myownhat.blogspot.com/
"Don't believe everything you think"
2009/3/11 Tennessee Leeuwenburg <tleeuwenburg@gmail.com>:
Is there a general strategy used in Python development which I should be aware of? i.e. is it customary to type-check every argument of an interface method? Or is it customary not to perform type checking up-front and simply allow the exception to occur deeper in the code? Are there performance issues surrounding defensive programming?
Generally we avoid checking types at all in Python because of ducking typing. The C interface must check types because they have to translate to the C level equivalents. If tests are failing from a C implementation on a Python implementation because of extensive type checking, I would be tempted to mark those tests as implementation details. However, in the case of this specific issue, I think rejecting bytes purposefully is good because it avoids programming errors. -- Regards, Benjamin
participants (2)
-
Benjamin Peterson -
Tennessee Leeuwenburg