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.

classification
Title: array.array.__deepcopy__() accepts a parameter of any type
Type: behavior Stage: resolved
Components: Argument Clinic, Extension Modules Versions: Python 3.10, Python 3.9, Python 3.8, Python 3.7, Python 3.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Elaphurus, josh.r, larry, serhiy.storchaka
Priority: normal Keywords:

Created on 2021-04-13 03:00 by Elaphurus, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (4)
msg390918 - (view) Author: MingZhe Hu (Elaphurus) * Date: 2021-04-13 03:00
The C implementation of foreign function array.array.__deepcopy__() is declared as follows:

https://github.com/python/cpython/blob/d9151cb45371836d39b6d53afb50c5bcd353c661/Modules/arraymodule.c#L855

The second argument is unused in the function body.

However, corresponding PyMethodDef is declared with `METH_O` flag, meaning one parameter should be passed to array.array.__deepcopy__() from the Python side:

https://github.com/python/cpython/blob/d9151cb45371836d39b6d53afb50c5bcd353c661/Modules/clinic/arraymodule.c.h#L30

This makes the following code legal:

```
import array
a = array.array('b',  [ord('g')])
a.__deepcopy__('str')
a.__deepcopy__(1)
a.__deepcopy__([1,'str'])
```

A parameter of ANY type can be passed to the foreign function, without effect on its semantic.

These code are clinic generated, and similar problems can be found for more foreign functions.
msg390920 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2021-04-13 03:56
__deepcopy__ is required to take a second argument by the rules of the copy module; the second argument is supposed to be a memo dictionary, but there's no reason to use it for array.array (it can't contain Python objects, and you only use the memo dictionary when recursing to Python objects you contain).

Sure, the second argument isn't being type-checked, but it's not used at all, and it's only supposed to be invoked indirectly via copy.deepcopy (that passes a dict).

Can you explain what is wrong here that needs to be fixed? Seems like a straightforward "protocol requires argument, but use case doesn't have anything to do with it, so it ignores it". Are you suggesting adding type-checks for something that never gets used?
msg390937 - (view) Author: MingZhe Hu (Elaphurus) * Date: 2021-04-13 08:34
copy.deepcopy() takes a memo argument for reason, but this memo object will not be used when passed to array.array.__deepcopy__(), that is, no matter called directly or not, as long as the C implementation of array.array.__deepcopy__() does not use the parameter(s) passed from the Python side, why not declare it using flag `METH_NOARGS`?

If I understand right, in following code, the memo passed to __deepcopy__() is meaningless:

https://github.com/python/cpython/blob/a4833883c9b81b6b272cc7c5b67fa1658b65304c/Lib/copy.py#L151-L153
msg390938 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2021-04-13 08:52
I you declare a method as METH_NOARGS, you would not able to pass any argument to it.

I concur with Josh. There is nothing wrong here.
History
Date User Action Args
2022-04-11 14:59:44adminsetgithub: 87990
2021-04-13 08:52:16serhiy.storchakasetstatus: open -> closed

nosy: + serhiy.storchaka
messages: + msg390938

resolution: not a bug
stage: resolved
2021-04-13 08:34:04Elaphurussetmessages: + msg390937
2021-04-13 03:56:40josh.rsetnosy: + josh.r
messages: + msg390920
2021-04-13 03:00:23Elaphuruscreate