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 — Update multiprocessing.managers.ListProxy and multiprocessing.managers.DictProxy · Issue #103134 · python/cpython

Update multiprocessing.managers.ListProxy and multiprocessing.managers.DictProxy #103134

New issue
Copy link
New issue
Copy link
Closed
Closed
Update multiprocessing.managers.ListProxy and multiprocessing.managers.DictProxy#103134
Copy link
Labels
3.13only security fixesonly security fixestopic-multiprocessingtype-featureA feature request or enhancementA feature request or enhancement

Description

@invisibleroads
invisibleroads
opened on Mar 30, 2023
Issue body actions

Feature or enhancement

Standard lists accept clear as a shortcut for del xs[:]

xs = ['a']
xs.clear()

However, multiprocessing.ListProxy omitted support for clear().

from multiprocessing import Manager

with Manager() as manager:
    xs = manager.list()
    xs.clear()

raises the following exception

AttributeError: 'ListProxy' object has no attribute 'clear'

Pitch

If clear is supported in a standard list, it should be supported in a multiprocessing list!

Previous discussion

This issue was not previously discussed.

Linked PRs

  • gh-103134: Update multiprocessing.managers.ListProxy and multiprocessing.managers.DictProxy  #103133

Activity

  1. invisibleroads
    added
    type-featureA feature request or enhancementA feature request or enhancement
    on Mar 30, 2023
  2. arhadthedev
    added
    topic-multiprocessing
    on Mar 30, 2023
  3. arhadthedev
    added this to Multiprocessing issueson Mar 30, 2023
  4. terryjreedy commented on Mar 30, 2023

    @terryjreedy
    terryjreedy
    on Mar 30, 2023
    Member
    More actions

    ListProxy was written before list.clear and list.copy were added in 3.3. Since manager.list has all the other list methods, it seems straightforward to add the new methods.

    Reacted by sunmy2019
  5. terryjreedy commented on Mar 30, 2023

    @terryjreedy
    terryjreedy
    on Mar 30, 2023
    Member
    More actions

    Dicts got reversed in 3.8 and | and |= in 3.9. I think we should expand this to updating all proxy types.

  6. invisibleroads
    added a commit that references this issue on Mar 31, 2023

    Update ListProxy and DictProxy

    a748d41
  7. invisibleroads commented on Mar 31, 2023

    @invisibleroads
    invisibleroads
    on Mar 31, 2023
    ContributorAuthor
    More actions

    Updated the pull request to add xs.copy and d.fromkeys, d | {}, {} | d, reversed(d), d |= {} as you recommended.

    Waiting to hear back from @benjaminp to see whether it is safe to replace BaseListProxy with ListProxy and just bring __iadd__ and __imul__ directly as you suggested.

    Also, is there a place to put unit tests? I guess to test this properly, we would need to launch two processes and check that changes in one process are reflected in changes in the other process... Not sure how we would write a unit test for that, although we can certainly test it manually.

  8. invisibleroads
    changed the title [-]Update ListProxy to add support for multiprocessing.Manager().list().clear()[/-] [+]Update multiprocessing.managers.ListProxy and multiprocessing.managers.DictProxy[/+] on Mar 31, 2023
  9. invisibleroads commented on Mar 31, 2023

    @invisibleroads
    invisibleroads
    on Mar 31, 2023
    ContributorAuthor
    More actions

    As an update, I did try removing BaseListProxy and adding __iadd__ and __imul__ directly to ListProxy but it didn't work. I'm not sure why. Here is the code that I used to test this functionality manually.

    from multiprocessing import Manager, Process
    
    def f(x):
        x += [1]
        x *= 2
        print(x)
    
    def g(d):
        d |= {'b': 2}
        print(d)
    
    with Manager() as manager:
    
        x = manager.list()
        x.append(0)
        p = Process(target=f, args=(x,))
        p.start()
        p.join()
        q = Process(target=print, args=(x,))
        q.start()
        q.join()
    
        d = manager.dict()
        d['a'] = 1
        p = Process(target=g, args=(d,))
        p.start()
        p.join()
        q = Process(target=print, args=(d,))
        q.start()
        q.join()
    

    RESULTS

    ACTUAL after replacing BaseListProxy with ListProxy (the __imul__ doesn't seem to work).
    ACTUAL when DictProxy is missing __ior__

    [0, 1, 0, 1]
    [0, 1]
    {'a': 1, 'b': 2}
    {'a': 1}
    

    EXPECTED and ACTUAL with current commits for this pull request (keep BaseListProxy and bring DictProxy.__ior__) -- works with current pull request

    [0, 1, 0, 1]
    [0, 1, 0, 1]
    {'a': 1, 'b': 2}
    {'a': 1, 'b': 2}
    
  10. sunmy2019 commented on Apr 2, 2023

    @sunmy2019
    sunmy2019
    on Apr 2, 2023
    Member
    More actions

    RESULTS

    ACTUAL after replacing BaseListProxy with ListProxy (the __imul__ doesn't seem to work). ACTUAL when DictProxy is missing __ior__

    [0, 1, 0, 1]
    [0, 1]
    {'a': 1, 'b': 2}
    {'a': 1}
    

    EXPECTED and ACTUAL with current commits for this pull request (keep BaseListProxy and bring DictProxy.__ior__) -- works with current pull request

    [0, 1, 0, 1]
    [0, 1, 0, 1]
    {'a': 1, 'b': 2}
    {'a': 1, 'b': 2}
    

    Digging for one hour, I found it actually pretty simple.

    Try this one out,

    def f(x):
        x += [1]
        print(type(x))
        x *= 2

    When you find x has type list but not <class 'multiprocessing.managers.ListProxy'>, you know you screwed up.

    class ListProxy(BaseListProxy):
        def __iadd__(self, value):
            self._callmethod('extend', (value,))
            return self
        def __imul__(self, value):
            self._callmethod('__imul__', (value,))
            return self

    This return self plays key role here. I understand the whole thing after seeing this.

    cpython/Lib/multiprocessing/managers.py

    Lines 808 to 811 in a0305c5

    def _callmethod(self, methodname, args=(), kwds={}):
    '''
    Try to call a method of the referent and return a copy of the result
    '''

  11. invisibleroads
    added a commit that references this issue on Apr 30, 2023

    Fix __ior__ and add tests thanks to python#103134 (comment) @sunmy2019

    1cf0985
  12. invisibleroads commented on Apr 30, 2023

    @invisibleroads
    invisibleroads
    on Apr 30, 2023
    ContributorAuthor
    More actions

    When you find x has type list but not <class 'multiprocessing.managers.ListProxy'>, you know you screwed up.

    def f(x):
        x += [1]
        print(type(x))
        x *= 2
    

    @sunmy2019 thanks so much for the important hint. I was able to make obj |= {'bar': 6} work properly after overriding __ior__ using the same technique used for ListProxy.

    BaseDictProxy = MakeProxyType('DictProxy', (
        '__contains__', '__delitem__', '__getitem__', '__ior__', '__iter__',
        '__len__', '__or__', '__reversed__', '__ror__', '__setitem__', 'clear',
        'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem',
        'setdefault', 'update', 'values',
        ))
    class DictProxy(BaseDictProxy):
        _method_to_typeid_ = {
            '__iter__': 'Iterator',
        }
        def __ior__(self, value):
            self._callmethod('__ior__', (value,))
            return self

    I finished adding the tests and the pull request is ready for review.

    Reacted by Roy Hyunjin Han
  13. arhadthedev
    added
    3.13only security fixesonly security fixes
    on May 20, 2023
  14. encukou
    added a commit that references this issue on May 20, 2024

    gh-103134: Update multiprocessing.managers.ListProxy and DictProxy (G…

    bbb4988
  15. encukou
    closed this as completedon May 20, 2024
  16. github-project-automation
    moved this to Done in Multiprocessing issueson May 20, 2024
  17. gpshead commented on May 20, 2024

    @gpshead
    gpshead
    on May 20, 2024
    Member
    More actions

    thanks for taking this on!

    Reacted by Roy Hyunjin Han
    Reacted by Roy Hyunjin Han
  18. estyxx
    added a commit that references this issue on Jul 17, 2024

    pythongh-103134: Update multiprocessing.managers.ListProxy and DictPr…

    df129f0
  19. gpshead
    added 2 commits that reference this issue on Nov 11, 2024

    pythongh-84559: pythongh-103134: Whats new 3.14 entries for multiproc…

    dd14fd0

    gh-84559: gh-103134: Whats new 3.14 entries for multiprocessing. (GH-…

    4f3253a
  20. picnixz
    added a commit that references this issue on Dec 8, 2024

    pythongh-84559: pythongh-103134: Whats new 3.14 entries for multiproc…

    2662c5e
  21. ebonnal
    added a commit that references this issue on Jan 12, 2025

    pythongh-84559: pythongh-103134: Whats new 3.14 entries for multiproc…

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13only security fixesonly security fixestopic-multiprocessingtype-featureA feature request or enhancementA feature request or enhancement

    Projects

    • Multiprocessing issues
      Status
      Done
      Show more project fields

    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.