msg266807 - (view) |
Author: SilentGhost (SilentGhost) * |
Date: 2016-06-01 07:58 |
This could only go in 3.6, but it needs proper documentation and test(s).
|
msg266813 - (view) |
Author: Ryan Petrello (ryan.petrello) |
Date: 2016-06-01 10:52 |
Thanks, I'll upload a new patch shortly that addresses these.
|
msg266832 - (view) |
Author: Yury Selivanov (yselivanov) * |
Date: 2016-06-01 18:17 |
Please don't commit this without my review.
|
msg266972 - (view) |
Author: Yury Selivanov (yselivanov) * |
Date: 2016-06-02 22:06 |
Nick, what do you think about this one?
I'm +1 to add this, but I'm not sure about the name for the argument. Do you have better ideas, or "skip_bound_arg" is good enough?
|
msg268932 - (view) |
Author: Ryan Petrello (ryan.petrello) |
Date: 2016-06-20 20:57 |
Yury/Nick,
Any word on this? I know it's minor, but I'd love to see this make it into Python3.6.
|
msg269016 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2016-06-21 19:43 |
Hi Ryan, sorry for the delayed response.
My own concern with this proposal is that I don't understand the use case for it. We changed the inspect.signature behaviour away from that of inspect.getfullargspec because we considered the latter behaviour to be *wrong*: it reported a parameter the already bound method didn't actually accept when called. The "skip_bound_arg" functionality then remains *within* the inspect module for the sake of providing backwards compatible implementations of getargspec and getfullargspec without duplicating a lot of other callable introspection logic.
If you can provide more information on the motivating use case, we can better determine if exposing this option directly is a suitable design response, or if there may be better alternatives available.
|
msg269071 - (view) |
Author: Ryan Petrello (ryan.petrello) |
Date: 2016-06-22 12:08 |
Nick,
My use case is an issue of backwards compatibility and multiple Python version support for a library that makes prolific use of the legacy argspec (args, varargs, varkw, defaults) namedtuple, *including* the bound self argument behavior. argspec and signature are quite different, and supporting a Py26-Py36 codebase that handles both simultaneously seemed like quite a burden, so I opted to write a compatibility shim that returned an Argspec-like object for all versions of Python; this seemed the simplest approach to bridge the gap in a codebase that supports Python 2.6 through 3.6, and it's the approach that I've seen other major libraries (like Django) take:
https://github.com/pecan/pecan/pull/61
I'm using a similar approach to Python 3.5's getfullargspec() implementation:
https://github.com/python/cpython/blob/3.5/Lib/inspect.py#L1069
...but I don't have a long-term public API for doing it (so I have to rely on the private inspect._signature_from_callable call, which seems icky).
|
msg269081 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2016-06-22 18:46 |
Are you able to use inspect.getfullargspec() on Python 3 rather than inspect.getargspec()?
While both are technically deprecated, only inspect.getargspec() actually emits a deprecation warning - inspect.getfullargspec() still works without complaint and is in no danger of being removed.
|
msg269082 - (view) |
Author: Ryan Petrello (ryan.petrello) |
Date: 2016-06-22 20:01 |
Nick,
My main reasoning for not using it is that it's marked as deprecated in the docstring, and I want to avoid relying on it if disappears in the future :)
Warnings or not, the shim that I wrote doesn't use any deprecated code, so that's why I took that approach.
|
msg269085 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2016-06-22 20:42 |
OK, so maybe the right answer here is to officially undeprecate inspect.getfullargspec(), as we definitely *don't* want people feeling obliged to write their own version of that, and potentially introducing inconsistencies between different tools.
Then the deprecation warning on inspect.getargspec() can be updated to point people towards "inspect.signature() or inspect.getfullargspec()", while the docs for getfullargspec() itself can be updated to say it isn't recommended for use in new code, rather than that it's deprecated.
|
msg269129 - (view) |
Author: Ryan Petrello (ryan.petrello) |
Date: 2016-06-23 18:06 |
Nick,
That seems reasonable to me :) I've updated my library to just use inspect.getfullargspec for Py3. Thanks for taking the time to walk through this with me!
|
msg269130 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2016-06-23 18:18 |
OK, as per the above discussion, I've changed the title of this issue to be to undeprecate inspect.getfullargspec().
That change involves two pieces:
- change the documented deprecation of inspect.getfullargspec() to instead be a recommendation to avoid using it in new code, and instead use inspect.signature()
- update the inspect.getargspec() documentation and programmatic deprecation warning to point to both inspect.signature() and inspect.getfullargspec() as potential replacements
That gives folks already using inspect.getfullargspec assurance that it isn't going away anytime soon (if ever), while folks using inspect.getargspec get a lower impact migration path to a more Python 3 friendly version of the callable introspection API.
|
msg270121 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2016-07-10 18:29 |
The existing patch no longer addresses the revised decision about the API (or the new title of the issue). So, we need a new patch.
|
msg270122 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2016-07-10 18:32 |
Also, this is now a documentation issue, though it does require a code change for the getargspec deprecation message.
|
msg281603 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2016-11-24 04:21 |
This just came up in a discussion on a urllib3 patch, so I'd like to fix it for 3.6.0rc1.
Ned, given that the code change here is just deleting the deprecation warning from getfullargspec() and rewording the one for getargspec(), does that seem OK for 3.6.0?
|
msg281604 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2016-11-24 04:35 |
When we undeprecate this, we should remove and reword the deprecation warnings in the next 3.5 maintenance release as well.
I'll need to decide on a way to indicate in the docs that some versions of 3.x.y will report a deprecation warning for getfullargspec() though - probably a "Changed in" note.
|
msg281605 - (view) |
Author: Ned Deily (ned.deily) * |
Date: 2016-11-24 05:12 |
Nick, that seems like the right thing to do. Thanks for following up on it.
|
msg281825 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2016-11-27 13:13 |
Initial patch attached. Key missing pieces:
- needs a What's New note
- needs to undeprecate inspect.getcallargs() as well (more on that below)
As my last couple of comments indicate, I'd forgotten that only getargspec() was programmatically deprecated, which means the sole code change is a rewording of the getargspec() warning to mention both signature() and getfullargspec().
The documentation changes are a bit more extensive, as I couldn't resist fixing the longstanding terminology error in the docs and docstrings, where these functions are mostly reporting *parameter* names, not argument names (callable arguments have values, not names).
I think the "versionchanged" note works well for indicating that folks aren't imagining things if they remembered seeing this function marked as deprecated.
However, I also went back and checked the 3.5 What's New, and that does mention the deprecations, so I'll need to do another version of this patch that includes a 3.6 What's New notice retracting those deprecations.
That check also reveals some other documented deprecations that should probably be reverted.
Firstly, getargvalues() and formatargvalues() are *frame* introspection functions, and hence have nothing whatsoever to do with inspect.signature(). The code and docs are just a bit confusing as they're interleaved with the callable introspection functions. I've filed that as a new issue: http://bugs.python.org/issue28814
Secondly, https://bugs.python.org/issue20438#msg254892 notes that inspect.getcallargs() has some behaviours that differ from Signature.bind in a way that's a bit of a pain to replicate on top of the latter. Similar to getfullargspec(), what do folks think of the idea of reverting that deprecation at least until 2.7 goes EOL?
(Noting for the record so folks don't wonder if it's an accidental oversight: I think formatargspec should retain its documented deprecation, as folks really are better off writing their own formatting function based on the data returned or switching to the new signature API)
|
msg281884 - (view) |
Author: Yury Selivanov (yselivanov) * |
Date: 2016-11-28 16:31 |
Nick, your patch LGTM. I'd only add to the getargspec section that getfullargspec is usually a drop-in replacement (I've yet to see code where it's not the case).
|
msg282174 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2016-12-01 13:22 |
Updated patch adding What's New and NEWS entries, and addressing Martin's review comments (mostly by accepting his suggestions).
I ended up leaving `inspect.getcallargs()` deprecated, and instead added a comment to issue 20438 noting how to achieve the bound args -> unbound args conversion in a general way: http://bugs.python.org/issue20438#msg282173
|
msg282234 - (view) |
Author: Roundup Robot (python-dev) |
Date: 2016-12-02 10:35 |
New changeset 14c2d93ffcb3 by Nick Coghlan in branch '3.6':
Issue #27172: Undeprecate inspect.getfullargspec()
https://hg.python.org/cpython/rev/14c2d93ffcb3
|
msg282235 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2016-12-02 10:38 |
I've pushed the change for 3.6.0rc1 based on Yury and Martin's review, but wasn't able to forward merge it to default due to merge conflicts on Misc/NEWS that I wasn't sure how to resolve.
|
msg282256 - (view) |
Author: Ned Deily (ned.deily) * |
Date: 2016-12-02 21:15 |
It looks like Serhiy took care of the merge to default in dd4c420b8e66.
|
msg282268 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2016-12-03 04:44 |
Thank you Serhiy!
That leaves this just as a pending update for 3.5.3 to bring it into line with 3.6.0.
I've reverted the stage to "needs patch" and removed the patch keyword, as the 3.5 patch will be slightly different:
- using 3.5.3 in the versionchanged notice
- adjusting the 3.5 What's New to change the list of deprecated inspect module APIs
|
msg292386 - (view) |
Author: Tim Graham (Tim.Graham) * |
Date: 2017-04-27 01:30 |
Does it seems likely that getfullargspec() will be deprecated after Python 2 is EOL? Django is currently reimplementing getargspec():
https://github.com/django/django/blob/8ab7ce8558792f41637d6f87f2a8a117e169dd18/django/utils/inspect.py#L4-L24
A pull request proposes to modify that implementation to behave as getfullargspec(): https://github.com/django/django/pull/8410
Django master now supports Python 3.4+, so I guess we would rather use getfullargspec() if it's not going to be deprecated in the future. The only downside is that it would introduce deprecation warnings for Python 3.5 users since those warnings haven't been removed yet. I guess Django could silence them.
|
msg292408 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2017-04-27 07:01 |
No, there are no plans to ever deprecate getfullargspec() again - it isn't hard to maintain indefinitely as a wrapper around inspect.Signature(), and it doesn't have the significant limitations that affected getargspec().
|
msg292410 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2017-04-27 07:05 |
Also, note that the programmatic deprecation warning change in the patch is to the warning for `getargspec()`, so that it recommends `getfullargspec()` rather than `Signature()`.
There's no runtime deprecation warning for `getfullargspec()` in any version of Python 3.x, so projects can use it freely, regardless of target version.
|
msg303936 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2017-10-09 09:36 |
Oops, we/I missed the window for also getting the deprecation removed from 3.5.x (as that branch is now in security-fix only mode).
Marking as resolved for 3.6 accordingly.
|
msg303960 - (view) |
Author: Larry Hastings (larry) * |
Date: 2017-10-09 14:10 |
Wait, what is all this nonsense?
inspect.getfullargspec is Python 3 only. It was added to support keyword-only parameters. Python 2 doesn't *have* keyword-only parameters, so it isn't needed there.
Check for yourself: Python 2 doesn't have inspect.getfullargspec.
https://docs.python.org/2/library/inspect.html#inspect.getargspec
We might consider un-deprecating inspect.getargspec() for supporting code supporting Py2 and Py3. But there's no point in un-deprecating inspect.getfullargspec() for that reason.
Nick: please *back out* your pointless, taffy-headed checkin.
|
msg303983 - (view) |
Author: Tim Graham (Tim.Graham) * |
Date: 2017-10-09 16:21 |
Perhaps the reason for the undeprecation could use some clarification. In a Python 3 only world (where Django's master branch is), I believe there's still usefulness for inspect.getfullargspec() -- see https://github.com/django/django/search?q=getfullargspec for usages.
|
msg304017 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2017-10-10 06:17 |
Larry, your personal insult is entirely unwelcome, unnecessary, and unappreciated, especially as it's wrong regarding the Python 2/3 compatibility concerns.
While getfullargspec() is indeed new in Python 3.x, it's also deliberately designed as a *drop-in replacement* for inspect.getargspec(). This means straddling Python 2 & 3 is straightforward, since you just need to toggle which API function you call (getargspec() on 2.7, getfullargspec() on 3.x).
This is *not* the case for switching to the inspect.signature() API: doing that for existing code that still supports Python 2.7 also requires switching to one of the third party backports of that API to 2.7, and then changing the way your own code models function signatures.
This is why getfullargspec() only received a documented deprecation, rather than a programmatic one. However, the combination of that notice in the documentation with the programmatic deprecation warning in getargspec() was enough to make people believe that in order to add Python 3 support, they *also* had to either switch to the inspect.signature() API, or else write and maintain their own version of getfullargspec().
That wasn't the intended outcome, and we have no plans to actually remove getfullargspec(), so I changed the wording in the getargspec() deprecation warning and the getfullargspec() documentation to better encourage the desired behaviour (i.e. inspect.signature() being used in new code, and existing code being migrated to the inspect.signature() API as developers find value in doing so)
|
msg304018 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2017-10-10 06:29 |
Note: the minor incompatibility that required getfullargspec() to be a separate API in the first place is the fact that it returns a 7 element named tuple instead of a 4 element one.
This means that hybrid 2/3 code needs to consistently use name based item access rather than tuple unpacking, but other than that, all code related to the first four fields can be identical across versions. (Code related to handling the extra three fields will naturally only be needed on 3.x)
|
msg307253 - (view) |
Author: Brett Cannon (brett.cannon) * |
Date: 2017-11-29 18:24 |
Nick pointed me at this issue for the undeprecation of inspect.getfullargspec(). While I'm fine with the un-deprecation for compatibility reasons, I would rather the function not last beyond Python 3 un-deprecated. Nick says, though that:
"""
... the undeprecation
isn't a Python 2/3 issue, it's a "tuples, lists and dicts are really
handy representations of things, and Python developers often prefer
them to more structured objects" issue.
The modern inspect.getfullargspec implementation is a relatively thin
wrapper around inspect.signature, and the only lossy part of the
output transformation is that you can't tell the difference between
positional-only and positional-or-keyword parameters.
"""
My argument is TOOWDI and as of right now there's 3 for getting parameter information for functions (of which only one is currently deprecated). I would also argue that if people want a "signature to core data structure" translation then that can be covered by a package on PyPI since even now getfullargspec() is lossy and we don't need that kind of pragmatic support in the stdlib for this.
|
msg307302 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2017-11-30 12:41 |
If there was a documented deprecation that said "Use <this PyPI package> instead", I'd be OK with that.
The part I wasn't OK with is multiple projects each copying & pasting their own variant of the getfullargspec code and accessing private inspect module APIs in order to get the old behaviour back.
So in order to move this to PyPI instead, we'd need to offer a completely public API that was equivalent to `_signature_from_callable(func, follow_wrapper_chains=False, skip_bound_arg=False, sigcls=Signature)`
`inspect.Signature.from_callable(func, follow_wrapped=False)` comes very close, but misses a subtlety where "getfullargspec" will mention "self" for bound methods, even though it's implicitly supplied, and doesn't need to be supplied by the caller.
That aspect could potentially just be deprecated outright though, with the PyPI replacement following inspect.signature's behaviour and reporting the actual call signature of the bound method.
|
msg307303 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2017-11-30 12:53 |
I'll also note that one possible alternative would be to accept Ryan's original proposal, which was to make "skip_bound_arg=False" part of the public API for `inspect.Signature.from_callable`.
Keeping `getfullargspec` around (but discouraged for new code), seems nicer to me than doing that, though, since the *only* use case we're aware of for that behaviour toggle is to be able to emulate inspect.getfullargspec() atop inspect.Signature().
TOOWTDI simply doesn't strike me as a good enough reason to break working code in this case - there *is* an obvious way for new code (inspect.signature), and there are plenty of other standard library APIs that we keep around primarily for backwards compatibility reasons, even though we don't necessarily recommend using them any more.
|
msg307337 - (view) |
Author: Brett Cannon (brett.cannon) * |
Date: 2017-11-30 18:39 |
I'm not saying we remove getfullargspec() **right now**, just that we don't keep it around long-term as it simply can't evolve to keep up with how rich our parameter support is today and might become in the future. And that's why, for me, the deprecation was enough to signal, "this code is here for now and you can use it, but you really need to be aware of some issues that are leading to it being removed". Now obviously you prefer the doc approach for this, Nick, and that's fine since this is quickly devolving into "agree to disagree" as while "there are plenty of other standard library APIs that we keep around primarily for backwards compatibility reasons", I personally would say we should be prepared to deprecate them for Python 4 (which is what I'm talking about here, not e.g. 3.8).
|
msg307363 - (view) |
Author: Nick Coghlan (ncoghlan) * |
Date: 2017-12-01 05:23 |
Independently of what we eventually decide to do for 4.0, there are some changes we could make at the documentation level to more clearly indicate "Even though this isn't deprecated, you still shouldn't use it for new code": https://bugs.python.org/issue32190
|
|
Date |
User |
Action |
Args |
2022-04-11 14:58:31 | admin | set | github: 71359 |
2019-05-11 04:32:59 | ncoghlan | set | status: open -> closed |
2018-01-28 03:47:00 | ncoghlan | set | assignee: ncoghlan -> |
2017-12-01 05:23:21 | ncoghlan | set | messages:
+ msg307363 |
2017-11-30 18:39:31 | brett.cannon | set | messages:
+ msg307337 |
2017-11-30 12:53:45 | ncoghlan | set | messages:
+ msg307303 |
2017-11-30 12:41:27 | ncoghlan | set | messages:
+ msg307302 |
2017-11-29 18:24:28 | brett.cannon | set | nosy:
+ brett.cannon messages:
+ msg307253
|
2017-10-10 06:29:48 | ncoghlan | set | messages:
+ msg304018 |
2017-10-10 06:17:56 | ncoghlan | set | messages:
+ msg304017 |
2017-10-09 16:21:50 | Tim.Graham | set | messages:
+ msg303983 |
2017-10-09 14:10:43 | larry | set | status: closed -> open
messages:
+ msg303960 |
2017-10-09 09:36:23 | ncoghlan | set | status: open -> closed versions:
+ Python 3.6, - Python 3.5 messages:
+ msg303936
resolution: fixed stage: backport needed -> resolved |
2017-04-27 07:05:26 | ncoghlan | set | messages:
+ msg292410 |
2017-04-27 07:01:37 | ncoghlan | set | priority: deferred blocker -> normal
messages:
+ msg292408 stage: needs patch -> backport needed |
2017-04-27 01:30:20 | Tim.Graham | set | nosy:
+ Tim.Graham messages:
+ msg292386
|
2017-04-01 05:47:44 | serhiy.storchaka | set | pull_requests:
- pull_request923 |
2017-03-31 16:36:18 | dstufft | set | pull_requests:
+ pull_request923 |
2016-12-03 04:44:16 | ncoghlan | set | stage: commit review -> needs patch messages:
+ msg282268 versions:
- Python 3.7 |
2016-12-02 21:15:32 | ned.deily | set | nosy:
+ serhiy.storchaka messages:
+ msg282256
|
2016-12-02 10:38:10 | ncoghlan | set | priority: release blocker -> deferred blocker
stage: needs patch -> commit review messages:
+ msg282235 versions:
- Python 3.6 |
2016-12-02 10:35:13 | python-dev | set | nosy:
+ python-dev messages:
+ msg282234
|
2016-12-01 13:22:33 | ncoghlan | set | files:
+ issue27172_undeprecate_getfullargspec_v2.diff
messages:
+ msg282174 |
2016-11-28 16:31:28 | yselivanov | set | messages:
+ msg281884 |
2016-11-27 13:13:20 | ncoghlan | set | files:
+ issue27172_undeprecate_getfullargspec.diff keywords:
+ patch messages:
+ msg281825
|
2016-11-24 05:12:02 | ned.deily | set | priority: normal -> release blocker versions:
+ Python 3.7 nosy:
+ larry
messages:
+ msg281605
|
2016-11-24 04:35:06 | ncoghlan | set | messages:
+ msg281604 versions:
+ Python 3.5 |
2016-11-24 04:21:25 | ncoghlan | set | assignee: ncoghlan
messages:
+ msg281603 nosy:
+ ned.deily |
2016-07-10 18:32:26 | r.david.murray | set | messages:
+ msg270122
assignee: yselivanov -> (no value) components:
+ Documentation, - Library (Lib) keywords:
- patch type: enhancement -> behavior |
2016-07-10 18:29:24 | r.david.murray | set | nosy:
+ r.david.murray
messages:
+ msg270121 stage: commit review -> needs patch |
2016-06-23 18:18:21 | ncoghlan | set | messages:
+ msg269130 title: Add skip_bound_arg argument to inspect.Signature.from_callable() -> Undeprecate inspect.getfullargspec() |
2016-06-23 18:06:17 | ryan.petrello | set | messages:
+ msg269129 |
2016-06-22 20:42:21 | ncoghlan | set | messages:
+ msg269085 |
2016-06-22 20:01:58 | ryan.petrello | set | messages:
+ msg269082 |
2016-06-22 18:46:01 | ncoghlan | set | messages:
+ msg269081 |
2016-06-22 12:08:34 | ryan.petrello | set | messages:
+ msg269071 |
2016-06-21 19:43:10 | ncoghlan | set | messages:
+ msg269016 |
2016-06-20 20:57:57 | ryan.petrello | set | messages:
+ msg268932 |
2016-06-02 22:06:56 | yselivanov | set | nosy:
+ ncoghlan messages:
+ msg266972
|
2016-06-01 19:09:04 | ryan.petrello | set | files:
+ signature-from-callable-skip-bound-arg.patch |
2016-06-01 18:35:39 | ryan.petrello | set | files:
+ signature-from-callable-skip-bound-arg.patch |
2016-06-01 18:22:00 | SilentGhost | set | assignee: yselivanov stage: patch review -> commit review |
2016-06-01 18:17:34 | yselivanov | set | messages:
+ msg266832 |
2016-06-01 18:10:19 | berker.peksag | set | stage: test needed -> patch review |
2016-06-01 17:27:06 | ryan.petrello | set | files:
+ signature-from-callable-skip-bound-arg.patch |
2016-06-01 11:46:48 | ryan.petrello | set | nosy:
+ eric.snow
|
2016-06-01 10:58:53 | ryan.petrello | set | files:
+ signature-from-callable-skip-bound-arg.patch |
2016-06-01 10:52:23 | ryan.petrello | set | messages:
+ msg266813 |
2016-06-01 07:58:08 | SilentGhost | set | versions:
- Python 3.5 nosy:
+ SilentGhost, yselivanov
messages:
+ msg266807
stage: test needed |
2016-06-01 04:17:26 | ryan.petrello | set | versions:
+ Python 3.5 |
2016-06-01 04:04:50 | ryan.petrello | create | |