Skip to content

Commit

Permalink
Implement Item.deepcopy()
Browse files Browse the repository at this point in the history
  • Loading branch information
Gallaecio committed Mar 8, 2019
1 parent c72ab1d commit 07c80b3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 10 deletions.
38 changes: 28 additions & 10 deletions docs/topics/items.rst
Expand Up @@ -40,6 +40,7 @@ objects. Here is an example::
name = scrapy.Field()
price = scrapy.Field()
stock = scrapy.Field()
tags = scrapy.Field()
last_updated = scrapy.Field(serializer=str)

.. note:: Those familiar with `Django`_ will notice that Scrapy Items are
Expand Down Expand Up @@ -158,16 +159,6 @@ To access all populated values, just use the typical `dict API`_::
Other common tasks
------------------

Copying items::

>>> product2 = Product(product)
>>> print(product2)
Product(name='Desktop PC', price=1000)

>>> product3 = product2.copy()
>>> print(product3)
Product(name='Desktop PC', price=1000)

Creating dicts from items::

>>> dict(product) # create a dict from all populated values
Expand All @@ -183,6 +174,33 @@ Creating items from dicts::
...
KeyError: 'Product does not support field: lala'

Copying items::

>>> product['tags'] = ['tag1']

>>> product2 = Product(product)
>>> print(product2)
Product(name='Desktop PC', price=1000, tags=['tag1'])

>>> product3 = product.copy()
>>> print(product3)
Product(name='Desktop PC', price=1000, tags=['tag1'])

>>> product4 = product.deepcopy()
>>> print(product4)
Product(name='Desktop PC', price=1000, tags=['tag1'])

>>> product['tags'].append('tag2')

>>> print(product2)
Product(name='Desktop PC', price=1000, tags=['tag1', 'tag2'])

>>> print(product3)
Product(name='Desktop PC', price=1000, tags=['tag1', 'tag2'])

>>> print(product4)
Product(name='Desktop PC', price=1000, tags=['tag1'])

Extending Items
===============

Expand Down
8 changes: 8 additions & 0 deletions scrapy/item.py
Expand Up @@ -6,6 +6,7 @@

from pprint import pformat
from collections import MutableMapping
from copy import deepcopy

from abc import ABCMeta
import six
Expand Down Expand Up @@ -96,6 +97,13 @@ def __repr__(self):
def copy(self):
return self.__class__(self)

def deepcopy(self):
"""Returns a `deep copy`_ of this item.
.. _deep copy: https://docs.python.org/library/copy.html#copy.deepcopy
"""
return deepcopy(self)


@six.add_metaclass(ItemMeta)
class Item(DictItem):
Expand Down
8 changes: 8 additions & 0 deletions tests/test_item.py
Expand Up @@ -249,6 +249,14 @@ class TestItem(Item):
copied_item['name'] = copied_item['name'].upper()
self.assertNotEqual(item['name'], copied_item['name'])

def test_deepcopy(self):
class TestItem(Item):
tags = Field()
item = TestItem({'tags': ['tag1']})
copied_item = item.deepcopy()
item['tags'].append('tag2')
assert item['tags'] != copied_item['tags']


class ItemMetaTest(unittest.TestCase):

Expand Down

0 comments on commit 07c80b3

Please sign in to comment.