TexSoup icon indicating copy to clipboard operation
TexSoup copied to clipboard

copy.copy and copy.deepcopy of a soup produces an error

Open pablo-angulo opened this issue 5 years ago • 1 comments

Hello: I would like to deepcopy a TexSoup, then modify the new soup with node.replace, but keep the old one for later use. I think this can be useful for other uses of TexSoup.

However this produces an error with any TexSoup:

In [22]: copy.deepcopy(soup)                                                                                                                               
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-22-631bebf40b2e> in <module>
----> 1 copy.deepcopy(soup)

/usr/lib/python3.8/copy.py in deepcopy(x, memo, _nil)
    159                     reductor = getattr(x, "__reduce_ex__", None)
    160                     if reductor is not None:
--> 161                         rv = reductor(4)
    162                     else:
    163                         reductor = getattr(x, "__reduce__", None)

TypeError: 'NoneType' object is not callable

In [23]: %debug                                                                                                                                            
> /usr/lib/python3.8/copy.py(161)deepcopy()
    159                     reductor = getattr(x, "__reduce_ex__", None)
    160                     if reductor is not None:
--> 161                         rv = reductor(4)
    162                     else:
    163                         reductor = getattr(x, "__reduce__", None)

ipdb> reductor                                                                                                                                             
<built-in method __reduce_ex__ of TexNode object at 0x7f824bb8c6a0>

The same happens for the shallow copy :

In [27]: soup = TexSoup('Hello')                                                                                                                           

In [28]: copy.copy(soup)                                                                                                                                   
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-28-25ef528ca711> in <module>
----> 1 copy.copy(soup)

/usr/lib/python3.8/copy.py in copy(x)
     90         reductor = getattr(x, "__reduce_ex__", None)
     91         if reductor is not None:
---> 92             rv = reductor(4)
     93         else:
     94             reductor = getattr(x, "__reduce__", None)

TypeError: 'NoneType' object is not callable

The error confused me at first, but it seems that __reduce__ and __reduce_ex__ are implemented as "Helper for pickle.", but they fail. I guess an explicit __deepcopy__ is required for TexNode. I guess I can deal with this: should I attempt a PR? any advice before I go?

pablo-angulo avatar Nov 07 '20 13:11 pablo-angulo

@pablo-angulo Interesting, a PR would definitely be welcome if you could spare the time. I'll start working on these issues starting from the oldest one, in a few days time.

  • I'd break it into three PRs: (1) implementing copy for texexprs. (2) implementing deep copy for texexprs. (3) implementing both for texnodes (which work by calling texexpr.deepcopy/.copy.
  • For deepcopies, I'd recursively call .children (like with repr for texexprs) and replace .content

alvinwan avatar Nov 20 '20 01:11 alvinwan