GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — dataclasses.astuple (and .asdict) do deepcopy on all fields · Issue #88071 · python/cpython

dataclasses.astuple (and .asdict) do deepcopy on all fields #88071

New issue
Copy link
New issue
Copy link
Closed
Closed
dataclasses.astuple (and .asdict) do deepcopy on all fields#88071
Copy link
Assignees
ericvsmith
Labels
3.10 (EOL)end of lifeend of life3.11only security fixesonly security fixes3.9 (EOL)end of lifeend of lifedocsDocumentation in the Doc dirDocumentation in the Doc dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

mandolaerik
mannequin
opened on Apr 21, 2021
Issue body actions
BPO 43905
Nosy @ericvsmith, @serhiy-storchaka, @miss-islington, @akulakov
PRs
  • bpo-43905: Expand dataclasses.astuple() and asdict() docs #26154
  • [3.10] bpo-43905: Expand dataclasses.astuple() and asdict() docs (GH-26154) #29851
  • [3.9] bpo-43905: Expand dataclasses.astuple() and asdict() docs (GH-26154) #29852
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/ericvsmith'
    closed_at = <Date 2021-11-29.18:34:32.678>
    created_at = <Date 2021-04-21.12:19:17.095>
    labels = ['3.11', 'type-bug', '3.9', '3.10', 'docs']
    title = 'dataclasses.astuple (and .asdict) do deepcopy on all fields'
    updated_at = <Date 2021-11-29.18:44:26.912>
    user = 'https://bugs.python.org/mandolaerik'

    bugs.python.org fields:

    activity = <Date 2021-11-29.18:44:26.912>
    actor = 'andrei.avk'
    assignee = 'eric.smith'
    closed = True
    closed_date = <Date 2021-11-29.18:34:32.678>
    closer = 'eric.smith'
    components = ['Documentation']
    creation = <Date 2021-04-21.12:19:17.095>
    creator = 'mandolaerik'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 43905
    keywords = ['patch']
    message_count = 14.0
    messages = ['391516', '391518', '391519', '391520', '394015', '394019', '396284', '407241', '407243', '407306', '407310', '407311', '407314', '407316']
    nosy_count = 5.0
    nosy_names = ['eric.smith', 'serhiy.storchaka', 'miss-islington', 'andrei.avk', 'mandolaerik']
    pr_nums = ['26154', '29851', '29852']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue43905'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    Linked PRs

    • gh-88071: Update docstrings of dataclass' astuple and asdict #101806

    Activity

    Next
    1. mandolaerik commented on Apr 21, 2021

      @mandolaerik
      mandolaerikmannequin
      on Apr 21, 2021
      MannequinAuthor
      More actions

      It seems that the 'dataclass.astuple' function does a deepcopy of all fields. This is not documented. Two problems:

      1. Dictionary keys that rely on object identity are ruined:

        import dataclasses
        @dataclasses.dataclass
        class Foo:
            key: object
        key = object()
        lut = {key: 5}
        (y,) = dataclasses.astuple(Foo(x))
        \# KeyError
        lut[y]
      2. dataclasses can only be converted to a tuple if all fields are serializable:

        import dataclasses
        @dataclasses.dataclass
        class Foo:
            f: object
        foo = Foo(open('test.py'))
        dataclasses.astuple(foo)

      ->

      TypeError: cannot pickle '_io.TextIOWrapper' object
      

      In my use case, I just want a list of all fields. I can do the following as a workaround:

      (getattr(foo, field.name) for field in dataclasses.fields(foo))

      Tested on Python 3.8.7 and 3.7.9.

    2. mandolaerik
      added
      stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
      3.7 (EOL)end of lifeend of life
      3.8 (EOL)end of lifeend of life
      on Apr 21, 2021
    3. ericvsmith commented on Apr 21, 2021

      @ericvsmith
      ericvsmith
      on Apr 21, 2021
      Member
      More actions

      Unfortunately this can't be changed, although I suppose it should be documented.

      In general I think this API was a mistake, and should not have been added. There are just too many cases where it doesn't do what you want, or where it fails.

      I'd like to deprecate it and remove it (along with asdict), but I fear that would be too disruptive.

      Your approach seems reasonable to me for your use case.

    4. ericvsmith
      assigned
      ericvsmith
      on Apr 21, 2021
    5. serhiy-storchaka commented on Apr 21, 2021

      @serhiy-storchaka
      serhiy-storchaka
      on Apr 21, 2021
      Member
      More actions

      Why deepcopy is used at all? It is a very specific feature which should not be used by default. If you want to make a deep copy of fields, you can call copy.deepcopy() explicitly.

          copy.deepcopy(dataclasses.astuple(obj))

      or

          dataclasses.astuple(copy.deepcopy(obj))
    6. ericvsmith commented on Apr 21, 2021

      @ericvsmith
      ericvsmith
      on Apr 21, 2021
      Member
      More actions

      The reason for the deep copying was to support changing a hierarchy of dataclasses into something that could be JSON serialized. But it didn't really work out. It recurses into dataclasses, namedtuples, lists, tuples, and dicts, and deep copies everything else.

      As I said, it's a design flaw.

    7. mandolaerik commented on May 20, 2021

      @mandolaerik
      mandolaerikmannequin
      on May 20, 2021
      MannequinAuthor
      More actions

      Would it make sense to make dataclasses iterable, like so?

          def __iter__(self):
              return (getattr(self, field.name) for field in fields(self))

      With that in place, deprecating astuple would maybe be less disruptive?

    8. ericvsmith commented on May 20, 2021

      @ericvsmith
      ericvsmith
      on May 20, 2021
      Member
      More actions

      No, iteration is explicitly a non-goal of PEP-557. See the section on namedtuple for why: https://www.python.org/dev/peps/pep-0557/#why-not-just-use-namedtuple

    9. akulakov commented on Jun 21, 2021

      @akulakov
      akulakov
      on Jun 21, 2021
      Contributor
      More actions

      I've added a PR here: #26154

    10. 15 remaining items

    11. ericvsmith
      added
      3.11only security fixesonly security fixes
      and removed
      3.7 (EOL)end of lifeend of life
      3.8 (EOL)end of lifeend of life
      on Nov 29, 2021
    12. miss-islington commented on Nov 29, 2021

      @miss-islington
      miss-islington
      on Nov 29, 2021
      Contributor
      More actions

      New changeset c1f93f0 by andrei kulakov in branch 'main':
      bpo-43905: Expand dataclasses.astuple() and asdict() docs (GH-26154)
      c1f93f0

    13. miss-islington commented on Nov 29, 2021

      @miss-islington
      miss-islington
      on Nov 29, 2021
      Contributor
      More actions

      New changeset 376b24e by Miss Islington (bot) in branch '3.9':
      bpo-43905: Expand dataclasses.astuple() and asdict() docs (GH-26154)
      376b24e

    14. miss-islington commented on Nov 29, 2021

      @miss-islington
      miss-islington
      on Nov 29, 2021
      Contributor
      More actions

      New changeset 32f1491 by Miss Islington (bot) in branch '3.10':
      bpo-43905: Expand dataclasses.astuple() and asdict() docs (GH-26154)
      32f1491

    15. ericvsmith commented on Nov 29, 2021

      @ericvsmith
      ericvsmith
      on Nov 29, 2021
      Member
      More actions

      Thanks, @andrei.avk!

    16. ericvsmith
      closed this as completedon Nov 29, 2021
    17. ericvsmith
      added
      type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
      on Nov 29, 2021
    18. ericvsmith
      closed this as completedon Nov 29, 2021
    19. ericvsmith
      added
      type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
      on Nov 29, 2021
    20. akulakov commented on Nov 29, 2021

      @akulakov
      akulakov
      on Nov 29, 2021
      Contributor
      More actions

      Thank you for reviewing Eric!

    21. ezio-melotti
      transferred this issue fromon Apr 10, 2022
    22. carljm
      added a commit that references this issue on Mar 11, 2023

      gh-88071: Update docstrings of dataclass' astuple and asdict (#101806)

      767d3a8
    23. iritkatriel
      added a commit that references this issue on Mar 12, 2023

      pythongh-88071: Update docstrings of dataclass' astuple and asdict (p…

      f8d4afb
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    • @ericvsmith
      ericvsmith

    Labels

    3.10 (EOL)end of lifeend of life3.11only security fixesonly security fixes3.9 (EOL)end of lifeend of lifedocsDocumentation in the Doc dirDocumentation in the Doc dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.