This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2011年08月18日 08:57 by arnau, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| example-argparse-type-function-called-twice.py | arnau, 2011年08月18日 08:57 | Example script showing the issue | ||
| py2.7-argparse-call-type-function-once.patch | arnau, 2011年08月22日 01:48 | Patch for tip (py2.7) hg branch (2) | review | |
| py3k-argparse-call-type-function-once.patch | arnau, 2011年08月22日 01:49 | Patch for tip (py3k) hg branch (2) | review | |
| argparse_test.py | flying sheep, 2011年11月24日 09:54 | test case for defaults | ||
| py2.7-argparse-call-type-function-once-v3.patch | arnau, 2011年11月25日 05:37 | Patch for tip (py2.7) hg branch (3) | ||
| py3k-argparse-call-type-function-once-v3.patch | arnau, 2011年11月25日 05:38 | Patch for tip (py3k) hg branch (3) | review | |
| py2.7-argparse-call-type-function-once-v4.patch | arnau, 2011年12月16日 02:24 | Patch for tip (py2.7) hg branch (4) -- 'is' rather than == | ||
| py3k-argparse-call-type-function-once-v4.patch | arnau, 2011年12月16日 02:24 | Patch for tip (py3k) hg branch (4) -- 'is' rather than == | ||
| fopatch | Mike.Meyer, 2012年05月03日 01:07 | Add test cases for non-existent default file for FileType. | ||
| py3k-argparse-call-type-function-once-v5.patch | bethard, 2012年07月21日 21:34 | review | ||
| Messages (21) | |||
|---|---|---|---|
| msg142306 - (view) | Author: Arnaud Fontaine (arnau) | Date: 2011年08月18日 08:57 | |
When specifying a function to be called in type keyword argument of add_argument(), the function is actually called twice (when a default value is set and then when the argument is given). While this may not be a problem in most cases (such as converting to an int for example), it is an issue for example when trying to open a file whose filename is given as a default value but is not accessible for whatever reason because the first call will fail whereas only the second should be done. I know this may sound like a twisted example but the type function should not be called twice anyhow IMHO. I tested with Python 2.7 and 3.2 from Debian packages only but the bug seems to be present in py3k and 2.7 hg branches as well. I have attached a small script showing the issue and two patches (for 2.7 and tip (py3k) hg branches), including an additional test case. All argparse tests pass well with 2.7 and 3.2. Hope that's ok. |
|||
| msg142620 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年08月21日 14:03 | |
Thanks for the patch. I commented on the code review site, you should have received an email. |
|||
| msg142653 - (view) | Author: Arnaud Fontaine (arnau) | Date: 2011年08月22日 01:46 | |
Thanks for the review. Sorry to send that here instead of the review page, but I get an error when replying: "Invalid XSRF token.".
> This looks good, especially if all existing tests still pass as you report, but
> I wonder about one thing: you have removed the part where the conversion
> function was applied to the default value, so I expected you to edit the other
> line were the conversion function was already called, but that’s not the case.
> Am I misunderstanding something?
Yes, sorry, I should have perhaps explained it in further details... Here are some examples:
* Example test case 1:
parser = argparse.ArgumentParser()
parser.add_argument('--foo', type=type_foo_func, default='foo')
parser.parse_args('--foo bar'.split())
=> Before the patch, type function is called in parse_known_args() for the default given in add_argument(), and then in _parse_known_args() for '--foo bar' given in parse_args above, whereas type function should have been called only for the second one.
* Example test case 2:
parser = argparse.ArgumentParser()
parser.add_argument('--foo', type=type_foo_func)
parser.parse_args('--foo bar'.split())
=> This was already working well before my patch.
* Example test case 3:
parser = argparse.ArgumentParser()
parser.add_argument('--foo', type=type_foo_func, default='foo')
parser.parse_args('')
=> type_foo_func is called after parsing arguments (none in this case) in my patch.
Therefore, my patch just moves the function type call after parsing the arguments (given to parse_args()) instead of before, only and only if it was not previously given in parse_args().
> http://bugs.python.org/review/12776/diff/3181/9898#newcode1985
> Lib/argparse.py:1985: if hasattr(namespace, action.dest) and \
> It is recommended to use parens to group multi-line statements, backslashes are
> error-prone.
I have just updated the patch on the bug report. Thanks.
|
|||
| msg144673 - (view) | Author: Arnaud Fontaine (arnau) | Date: 2011年09月30日 06:08 | |
Any news about applying these patches? |
|||
| msg148234 - (view) | Author: (flying sheep) * | Date: 2011年11月24日 09:54 | |
this is annoying: i’m creating a reindentation script that reindents any valid python script. the user can specify if, and how many spaces he/she wants to use per indentation level. `0` or leaving the option out means "one tab per level". if the argument is given, appended code works as intended. but in the default case, the code fails for any of the two default values i tried. i would expect that one of the default values works: either `0`, if the default value *is* converted via the `type` function, or `"\t"` if the default value bypasses it. it seems that argparse applies the `type` function to the default instantly, and then to the argument (be it the already-converted default or a passed option). this breaks `type` functions which aren’t reflexive for values from their result set, i.e.: `t(x) = y => t(y) = y` must be true for all `x` that the function can handle |
|||
| msg148235 - (view) | Author: Arnaud Fontaine (arnau) | Date: 2011年11月24日 10:20 | |
Does the patch I attached fix your issue? |
|||
| msg148239 - (view) | Author: (flying sheep) * | Date: 2011年11月24日 10:34 | |
i don’t know, since i get python from the ubuntu repositories, sorry. in which python release will this patch first be integrated? |
|||
| msg148241 - (view) | Author: Arnaud Fontaine (arnau) | Date: 2011年11月24日 11:00 | |
It would definitely help if you could apply the patch for Python 2.7 manually on your local installation (after making a backup of course). You can just download the patch for Python 2.7 then (only the first part of the patch can be applied, the second part is for the test so it doesn't matter): # cd /usr/lib/python2.7/ # patch -b -p2 -i /PATH/TO/THE/PATCH Thanks much. |
|||
| msg148250 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2011年11月24日 13:53 | |
Mucking with your installed Python is probably a bad idea, and it may also be an old version (compared to the current development version which has seen hundreds of changes) where testing the patch would not give useful results. Please see the devguide. |
|||
| msg148303 - (view) | Author: Arnaud Fontaine (arnau) | Date: 2011年11月25日 05:34 | |
I have had a look at the issue more closely and my initial patch was not completely right as it didn't work properly with argparse_test.py despite all tests passing. Therefore, I have amended my patch to not check whether action.default was a basestring which didn't make sense at all, but check instead if action.default is None (action.default default value is None if not given to add_argument as far as I understand). I also added a test for the issue reported above as it was missing and ran patchcheck to make sure everything was fine. All the tests (include argparse_test.py) passes without problem. Could you please apply them? Many thanks. |
|||
| msg148304 - (view) | Author: Arnaud Fontaine (arnau) | Date: 2011年11月25日 05:43 | |
BTW, about argparse_test, the default should be either '0' or 0 but not '\t' AFAIK because even the default value is converted using the given type function. It fails even with the last 2.7 version but it works well with my patch... |
|||
| msg149526 - (view) | Author: Steven Bethard (bethard) * (Python committer) | Date: 2011年12月15日 10:47 | |
Could you add a test to verify that custom actions are still getting the converted values passed to their __call__? I suspect this may not be happening under the current patch - if that's the case, you may also need to add conversions in _get_values, where the lines look like "value = action.default". Also, "action.default == getattr(namespace, action.dest)" should probably use "is" instead of "==". Other than that, the patch looks okay. |
|||
| msg149590 - (view) | Author: Arnaud Fontaine (arnau) | Date: 2011年12月16日 02:20 | |
> Could you add a test to verify that custom actions are still getting
> the converted values passed to their __call__? I suspect this may not
> be happening under the current patch - if that's the case, you may
> also need to add conversions in _get_values, where the lines look like
> "value = action.default".
There seems to be already a test for that, namely TestActionUserDefined,
which use type=float and type=int. The value is properly converted to
{int,float} when passed to __call__(). Just in case, I also tested with
a 'type' function I defined myself (which only returns float()) for
OptionalAction and it's working fine.
> Also, "action.default == getattr(namespace, action.dest)" should
> probably use "is" instead of "==".
Good point, it would be much better. Thanks for the advice. I have just
modified the patch with that.
|
|||
| msg151988 - (view) | Author: Arnaud Fontaine (arnau) | Date: 2012年01月26日 02:55 | |
ping? |
|||
| msg156316 - (view) | Author: Arnaud Fontaine (arnau) | Date: 2012年03月19日 05:15 | |
Could you please apply this patch? It's been 4 months without reply now... |
|||
| msg159826 - (view) | Author: Mike Meyer (Mike.Meyer) | Date: 2012年05月03日 01:07 | |
I've just verified that this patch also fixes 13824 and 11839. The attached patchfile adds a test to verify that using a non-existent default file fails if you don't specify the argument, and succeeds if you do. Could someone please apply it? |
|||
| msg159827 - (view) | Author: Mike Meyer (Mike.Meyer) | Date: 2012年05月03日 01:14 | |
Sorry - got ahead of myself. It doesn't fix 13824. A deeper reading reveals that the problem wasn't quite what I thought it on first glance. |
|||
| msg166076 - (view) | Author: Steven Bethard (bethard) * (Python committer) | Date: 2012年07月21日 21:34 | |
The patch looks good to me. I've updated it for trunk and to include Mike Meyer's additional test. All argparse tests pass. Anyone who's able to commit and backport, please do. (I should be able to commit myself, but it's now been too long and my SSH key seems to no longer work. I'll eventually get this sorted out, but as you may have noticed, I don't have much time for argparse these days, so best not to wait on me.) |
|||
| msg169608 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2012年09月01日 03:16 | |
New changeset 1b614921aefa by R David Murray in branch '3.2': #12776,#11839: call argparse type function only once. http://hg.python.org/cpython/rev/1b614921aefa New changeset 74f6d87cd471 by R David Murray in branch 'default': Merge #12776,#11839: call argparse type function only once. http://hg.python.org/cpython/rev/74f6d87cd471 New changeset 62b5667ef2f4 by R David Murray in branch '2.7': #12776,#11839: call argparse type function only once. http://hg.python.org/cpython/rev/62b5667ef2f4 |
|||
| msg169610 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2012年09月01日 03:18 | |
Thanks, Arnaud and Mike. (And Steven, of course :) |
|||
| msg185683 - (view) | Author: Éric Araujo (eric.araujo) * (Python committer) | Date: 2013年03月31日 21:53 | |
FTR a contributor to #13271 (--help should work even if a type converter fails) indicated that it’s fixed by this patch, so it may be good to add a regression test. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:20 | admin | set | github: 56985 |
| 2014年05月30日 02:44:44 | paul.j3 | set | nosy:
+ paul.j3 |
| 2013年03月31日 21:53:24 | eric.araujo | set | messages: + msg185683 |
| 2013年03月31日 21:51:07 | eric.araujo | link | issue13271 superseder |
| 2012年09月01日 03:18:24 | r.david.murray | set | status: open -> closed nosy: + r.david.murray messages: + msg169610 resolution: fixed stage: resolved |
| 2012年09月01日 03:16:47 | python-dev | set | nosy:
+ python-dev messages: + msg169608 |
| 2012年08月31日 17:34:22 | bethard | link | issue15832 superseder |
| 2012年07月21日 21:34:24 | bethard | set | files:
+ py3k-argparse-call-type-function-once-v5.patch messages: + msg166076 |
| 2012年05月03日 01:14:12 | Mike.Meyer | set | messages: + msg159827 |
| 2012年05月03日 01:07:49 | Mike.Meyer | set | files:
+ fopatch nosy: + Mike.Meyer messages: + msg159826 |
| 2012年03月19日 05:15:20 | arnau | set | messages: + msg156316 |
| 2012年01月26日 02:55:52 | arnau | set | messages: + msg151988 |
| 2011年12月16日 02:24:29 | arnau | set | files: + py3k-argparse-call-type-function-once-v4.patch |
| 2011年12月16日 02:24:04 | arnau | set | files: + py2.7-argparse-call-type-function-once-v4.patch |
| 2011年12月16日 02:20:56 | arnau | set | messages: + msg149590 |
| 2011年12月15日 10:47:29 | bethard | set | messages: + msg149526 |
| 2011年11月25日 05:43:20 | arnau | set | messages: + msg148304 |
| 2011年11月25日 05:38:11 | arnau | set | files: + py3k-argparse-call-type-function-once-v3.patch |
| 2011年11月25日 05:37:01 | arnau | set | files: + py2.7-argparse-call-type-function-once-v3.patch |
| 2011年11月25日 05:34:55 | arnau | set | messages: + msg148303 |
| 2011年11月24日 13:53:07 | eric.araujo | set | messages: + msg148250 |
| 2011年11月24日 11:00:17 | arnau | set | messages: + msg148241 |
| 2011年11月24日 10:34:00 | flying sheep | set | messages: + msg148239 |
| 2011年11月24日 10:20:09 | arnau | set | messages: + msg148235 |
| 2011年11月24日 09:54:06 | flying sheep | set | files:
+ argparse_test.py nosy: + flying sheep messages: + msg148234 |
| 2011年09月30日 06:08:10 | arnau | set | messages: + msg144673 |
| 2011年08月22日 01:49:03 | arnau | set | files: + py3k-argparse-call-type-function-once.patch |
| 2011年08月22日 01:48:51 | arnau | set | files: + py2.7-argparse-call-type-function-once.patch |
| 2011年08月22日 01:47:34 | arnau | set | files: - py3k-argparse-call-type-function-once.patch |
| 2011年08月22日 01:47:27 | arnau | set | files: - py2.7-argparse-call-type-function-once.patch |
| 2011年08月22日 01:46:15 | arnau | set | messages: + msg142653 |
| 2011年08月21日 14:03:45 | eric.araujo | set | nosy:
+ eric.araujo messages: + msg142620 versions: + Python 3.3 |
| 2011年08月18日 16:01:15 | ned.deily | set | nosy:
+ bethard |
| 2011年08月18日 08:59:47 | arnau | set | files: + py3k-argparse-call-type-function-once.patch |
| 2011年08月18日 08:59:22 | arnau | set | files:
+ py2.7-argparse-call-type-function-once.patch keywords: + patch |
| 2011年08月18日 08:57:57 | arnau | create | |