Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

function.__type_params__ and type.__type_params__ should be writable #104600

Closed
JelleZijlstra opened this issue May 18, 2023 · 6 comments · Fixed by python/peps#3457
Closed

function.__type_params__ and type.__type_params__ should be writable #104600

JelleZijlstra opened this issue May 18, 2023 · 6 comments · Fixed by python/peps#3457
Assignees
Labels
3.12 bugs and security fixes topic-typing type-feature A feature request or enhancement

Comments

@JelleZijlstra
Copy link
Member

JelleZijlstra commented May 18, 2023

The PEP-695 implementation added a new attribute __type_params__ to functions. I made this field read-only, but I realized there is a use case for writing to it: functools.wraps, when wrapping a generic function, should add the .__type_params__ to the wrapper. Making it writable is also more consistent with other fields on functions, as even the __name__ of functions is writable.

The PEP also adds a __type_params__ attribute to classes and type aliases. For classes it's already writable (it's just stored in the type's __dict__). For type aliases it's readonly, but as I don't see a use case for mutating a type alias's __type_params__, I'd like to keep it that way.

Linked PRs

@AlexWaygood
Copy link
Member

AlexWaygood commented May 18, 2023

For classes it's already writable (it's just stored in the type's __dict__).

Small correction: as noted in #104616, it's not actually writeable on class objects either at the moment (and probably should be, for similar reasons):

Running Debug|x64 interpreter...
Python 3.12.0a7+ (heads/main:cfa517d5a6, May 18 2023, 17:12:51) [MSC v.1932 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo[T]: ...
...
>>> Foo.__type_params__ = ("bar",)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: attribute '__type_params__' of 'type' objects is not writable
>>> class Bar: ...
...
>>> Bar.__type_params__ = ("bar",)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: attribute '__type_params__' of 'type' objects is not writable

@JelleZijlstra JelleZijlstra changed the title function.__type_params__ should be writable function.__type_params__ and type.__type_params__ should be writable May 18, 2023
JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this issue May 18, 2023
JelleZijlstra added a commit that referenced this issue May 19, 2023
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
carljm added a commit to gsallam/cpython_with_perfmap_apii that referenced this issue May 20, 2023
* main: (30 commits)
  pythongh-103987: fix several crashes in mmap module (python#103990)
  docs: fix wrong indentation causing rendering error in dis page (python#104661)
  pythongh-94906: Support multiple steps in math.nextafter (python#103881)
  pythongh-104472: Skip `test_subprocess.ProcessTestCase.test_empty_env` if ASAN is enabled (python#104667)
  pythongh-103839: Allow building Tkinter against Tcl 8.7 without external libtommath (pythonGH-103842)
  pythongh-85984: New additions and improvements to the tty library. (python#101832)
  pythongh-104659: Consolidate python examples in enum documentation (python#104665)
  pythongh-92248: Deprecate `type`, `choices`, `metavar` parameters of `argparse.BooleanOptionalAction` (python#103678)
  pythongh-104645: fix error handling in marshal tests (python#104646)
  pythongh-104600: Make type.__type_params__ writable (python#104634)
  pythongh-104602: Add additional test for listcomp with lambda (python#104639)
  pythongh-104640: Disallow walrus in comprehension within type scopes (python#104641)
  pythongh-103921: Rename "type" header in argparse docs (python#104654)
  Improve readability of `typing._ProtocolMeta.__instancecheck__` (python#104649)
  pythongh-96522: Fix deadlock in pty.spawn (python#96639)
  pythonGH-102818: Do not call `PyTraceBack_Here` in sys.settrace trampoline.  (pythonGH-104579)
  pythonGH-103545: Add macOS specific constants for ``os.setpriority`` to ``os`` (python#104606)
  pythongh-104623: Update macOS installer to SQLite 3.42.0 (pythonGH-104624)
  pythongh-104619: never leak comprehension locals to outer locals() (python#104637)
  pythongh-104602: ensure all cellvars are known up front (python#104603)
  ...
@sobolevn
Copy link
Member

Sorry, but now PEP is misleading:

A new read-only attribute called __type_params__ is available on generic classes, functions, and type aliases.

But, since it is now writtable (on classes as well):

>>> class A[X]: ...
... 
>>> A.__type_params__
(X,)
>>> A.__type_params__ = ()
>>> A.__type_params__
()

Shouldn't the PEP be updated? Or do you want to make this "implementation detail" private?

@JelleZijlstra
Copy link
Member Author

Good catch, I missed that the PEP explicitly said this. I think we can just update the PEP, cc @erictraut @gvanrossum. See my message above for the argument why these should be writable.

@erictraut
Copy link
Contributor

Sounds reasonable to me.

@JelleZijlstra
Copy link
Member Author

Reopening to remind myself to do that

@JelleZijlstra JelleZijlstra reopened this Aug 17, 2023
JelleZijlstra added a commit to JelleZijlstra/peps that referenced this issue Oct 1, 2023
Fixes python/cpython#104600.

We realized that the attribute should be writable on functions and
classes for the benefit of wrappers such as @functools.wraps.
JelleZijlstra added a commit to python/peps that referenced this issue Oct 3, 2023
Fixes python/cpython#104600.

We realized that the attribute should be writable on functions and
classes for the benefit of wrappers such as @functools.wraps.
@makslevental
Copy link

Sorry for commenting on a closed issue but can someone give me a quick word on why this is like this:

def wtfbbq[M, K, N]():
    print(type(M), type(K), type(N))

wtfbbq.__type_params__ = (32, 32, 32)

wtfbbq()

>>> <class 'typing.TypeVar'> <class 'typing.TypeVar'> <class 'typing.TypeVar'>

I expected some transmutation here but I guess in order to actually make the transmutation happen I need to update both wtfbbq.__code__.co_freevars and wtfbbq.__closure__?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 bugs and security fixes topic-typing type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants