<p dir="auto">I am seeing frequent deadlocks when running tasks simplified to the below.  (I purged out all the logging and a few database interactions to keep things clear.)  Calling the task that calls everything else usually runs &lt;15 tasks before locking, and restarting the workers a few times eventually clears up whatever the problem is (with the remaining tasks running to completion).  I realize that the issue is most likely with my code, but would appreciate any advice; I do not see much coverage of class based tasks and wonder if something is wrong there, and do not see any errors or exceptions in my logs.  Also, this might be a duplicate of <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="14166681" data-permission-text="Title is private" data-url="https://github.com/celery/celery/issues/1352" data-hovercard-type="issue" data-hovercard-url="/celery/celery/issues/1352/hovercard" href="https://github.com/celery/celery/issues/1352">#1352</a>; I am willing to move to Celery 3.1.7 to test, but it will take a bit due to required project restructuring.</p>
<p dir="auto">Celery worker start:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="python app/manage.py celeryd -E  --loglevel=INFO -Q db_upload,default,api_call,management,rr -c 1"><pre class="notranslate"><code class="notranslate">python app/manage.py celeryd -E  --loglevel=INFO -Q db_upload,default,api_call,management,rr -c 1
</code></pre></div>
<p dir="auto">Versioning:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" celery==3.0.19
 celery-with-redis==3.0
 django-celery==3.0.17
 kombu==2.5.10
 billiard==2.7.3.28"><pre class="notranslate"><code class="notranslate"> celery==3.0.19
 celery-with-redis==3.0
 django-celery==3.0.17
 kombu==2.5.10
 billiard==2.7.3.28
</code></pre></div>
<p dir="auto">Celery config:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="import djcelery
djcelery.setup_loader()
BROKER_URL = getenv('CLOUDAMQP_URL')
CELERY_RESULT_BACKEND = getenv('REDISTOGO_URL')

BROKER_POOL_LIMIT = int(getenv('BROKER_POOL_LIMIT', 1)) #1
BROKER_CONNECTION_TIMEOUT = int(getenv('BROKER_CONNECTION_TIMEOUT')) #6
CELERYD_CONCURRENCY = int(getenv('CELERYD_CONCURRENCY')) #1
CELERY_TASK_RESULT_EXPIRES = int(getenv('RESULT_EXPIRY_RATE')) 600
CELERY_IGNORE_RESULT = getenv('CELERY_IGNORE_RESULT') == 'True' #False
CELERYD_TASK_TIME_LIMIT = int(getenv('CELERYD_TASK_TIME_LIMIT')) #600
CELERY_REDIS_MAX_CONNECTIONS = int(getenv('CELERY_REDIS_MAX_CONNECTIONS')) #40

CELERY_IMPORTS = (&quot;app.management.tasks.api_calls&quot;,)
BROKER_CONNECTION_RETRY = True
CELERY_STORE_ERRORS_EVEN_IF_IGNORED = True
CELERY_ACKS_LATE = True
CELERYD_TASK_SOFT_TIME_LIMIT = 59
CELERY_SEND_TASK_ERROR_EMAILS = True"><pre class="notranslate"><code class="notranslate">import djcelery
djcelery.setup_loader()
BROKER_URL = getenv('CLOUDAMQP_URL')
CELERY_RESULT_BACKEND = getenv('REDISTOGO_URL')

BROKER_POOL_LIMIT = int(getenv('BROKER_POOL_LIMIT', 1)) #1
BROKER_CONNECTION_TIMEOUT = int(getenv('BROKER_CONNECTION_TIMEOUT')) #6
CELERYD_CONCURRENCY = int(getenv('CELERYD_CONCURRENCY')) #1
CELERY_TASK_RESULT_EXPIRES = int(getenv('RESULT_EXPIRY_RATE')) 600
CELERY_IGNORE_RESULT = getenv('CELERY_IGNORE_RESULT') == 'True' #False
CELERYD_TASK_TIME_LIMIT = int(getenv('CELERYD_TASK_TIME_LIMIT')) #600
CELERY_REDIS_MAX_CONNECTIONS = int(getenv('CELERY_REDIS_MAX_CONNECTIONS')) #40

CELERY_IMPORTS = ("app.management.tasks.api_calls",)
BROKER_CONNECTION_RETRY = True
CELERY_STORE_ERRORS_EVEN_IF_IGNORED = True
CELERY_ACKS_LATE = True
CELERYD_TASK_SOFT_TIME_LIMIT = 59
CELERY_SEND_TASK_ERROR_EMAILS = True
</code></pre></div>
<p dir="auto">Tasks:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="class BaseTask(Task):

    abstract=True
    def __call__(self, *args, **kwargs):
        #logger.info(&quot;Starting to run&quot;)
        self.api_context = kwargs['api_context']
        del kwargs['api_context']
        return super(BaseTask, self).__call__(*args, **kwargs)


class ApiFollower(Task):

    abstract=True
    def __call__(self, *args, **kwargs):
        self.result = args[0].get('result',{})
        self.api_context = args[0].get('api_context',{})
        return super(ApiFollower, self).__call__(*args, **kwargs)


class RefreshRecords(BaseTask):

    def run(self):
        check_list = get_users()
        for counter, user in enumerate(check_list, start = 1):
            context = ApiContext()
            context.account_id=user.id

            if self.api_context.records_requested is None:
                context.records_requested = 20
            else:
                context.records_requested = self.api_context.records_requested

            if self.api_context.records_desired is None:
                context.records_desired = 20
            else:
                context.records_desired = self.api_context.records_desired

            context.deepcopy=True
            context.start_scrape_time=now()
            context.last_scrape_time=user.last_scrape_time
            ac = ApiCall()
            rr = RetrieveRecords()
            chain(vac.s(mode='&lt;mode&gt;',api_context=context),rr.s()).delay()
tasks.register(RefreshRecords)


class ApiCall(BaseTask):
    def run(self, mode, **kwargs):
        self.api_context.key = API_KEY
        modeDict = {&lt;name: url several times&gt;}
        try:
            url = modeDict[mode]
        except KeyError:
            logger.info(&quot;Keyerrors!&quot;)

        URL = url + '?' + urlencode(self.api_context.toUrlDict(mode))

        # Exception handling for the URL opening.
        try:
            pageaccess = urllib2.urlopen(URL, timeout=5)
        except urllib2.HTTPError, err:
            if err.code in [104, 111, 401, 403, 404, 500, 503]:
                self.retry(mode=mode)
            else:
                self.retry(mode=mode)
        except (BadStatusLine, urllib2.URLError, ssl.SSLError, socket.timeout) as err:
            self.retry(mode=mode)

        data = json.loads(pageaccess.read())
        data['api_context'] = self.api_context
        return data
tasks.register(ApiCall)


class RetrieveRecords(ApiFollower):
    &quot;&quot;&quot;This is tricky.  The API lets you take slices of data, but you only know the indices to use in the call from the previously taken slices.  Further, to get actual information for the records in a slice, you need another API call.  Here we see if the previous call worked, spawn the detail calls as needed, and either hit the API again or finish up, depending on whether we wanted any more records.&quot;&quot;&quot;
    def run(self, urldata):
        try:
            if self.result['status'] == 1:
                self.spawnDetailCalls()
                if self.moreResultsLeft():
                    self.rebound()
                #Successful closeout
                else:
                    logger.info(&quot;Cleaning up&quot;)
                    self.cleanup()
                return True
            else:
                logger.error(&quot;Unhandled status: &quot;+str(self.result['status']))
                return True
        except Exception, err:
            logger.error(&quot;ERROR!:{0}&quot;.format(err))
            return False

    def rebound(self):
        self.api_context.start_at_record_id = self.result['information'][-1]['id']
        ac = ApiCall()
        rr = RetrieveRecords()
        pass_context = deepcopy(self.api_context)
        chain(ac.s(mode='&lt;mode&gt;',api_context=pass_context), rr.s()).delay()

    def cleanup(self):
        &lt;do stuff&gt;

    def spawnDetailCalls(self):
        for result in self.result['information']:
            ac = ApiCall()
            ud = UploadData()
            self.api_context.record_id=result['record_id']
            self.api_context.processed+=1
            pass_context = deepcopy(self.api_context)
            chain(ac.s(mode='&lt;mode&gt;',api_context=pass_context), ud.s()).delay()

    def moreResultsLeft(self):
        if self.result['results_remaining'] == 0:
            return False
        elif self.api_context.processed &gt;= self.api_context.records_desired:
            return False
        else:
            if self.api_context.deepcopy is False:
                return self.api_context.last_scrape_time &lt; self.result['information'][-1]['start_time']
            else:
                return True
tasks.register(RetrieveRecords)"><pre class="notranslate"><code class="notranslate">class BaseTask(Task):

    abstract=True
    def __call__(self, *args, **kwargs):
        #logger.info("Starting to run")
        self.api_context = kwargs['api_context']
        del kwargs['api_context']
        return super(BaseTask, self).__call__(*args, **kwargs)


class ApiFollower(Task):

    abstract=True
    def __call__(self, *args, **kwargs):
        self.result = args[0].get('result',{})
        self.api_context = args[0].get('api_context',{})
        return super(ApiFollower, self).__call__(*args, **kwargs)


class RefreshRecords(BaseTask):

    def run(self):
        check_list = get_users()
        for counter, user in enumerate(check_list, start = 1):
            context = ApiContext()
            context.account_id=user.id

            if self.api_context.records_requested is None:
                context.records_requested = 20
            else:
                context.records_requested = self.api_context.records_requested

            if self.api_context.records_desired is None:
                context.records_desired = 20
            else:
                context.records_desired = self.api_context.records_desired

            context.deepcopy=True
            context.start_scrape_time=now()
            context.last_scrape_time=user.last_scrape_time
            ac = ApiCall()
            rr = RetrieveRecords()
            chain(vac.s(mode='&lt;mode&gt;',api_context=context),rr.s()).delay()
tasks.register(RefreshRecords)


class ApiCall(BaseTask):
    def run(self, mode, **kwargs):
        self.api_context.key = API_KEY
        modeDict = {&lt;name: url several times&gt;}
        try:
            url = modeDict[mode]
        except KeyError:
            logger.info("Keyerrors!")

        URL = url + '?' + urlencode(self.api_context.toUrlDict(mode))

        # Exception handling for the URL opening.
        try:
            pageaccess = urllib2.urlopen(URL, timeout=5)
        except urllib2.HTTPError, err:
            if err.code in [104, 111, 401, 403, 404, 500, 503]:
                self.retry(mode=mode)
            else:
                self.retry(mode=mode)
        except (BadStatusLine, urllib2.URLError, ssl.SSLError, socket.timeout) as err:
            self.retry(mode=mode)

        data = json.loads(pageaccess.read())
        data['api_context'] = self.api_context
        return data
tasks.register(ApiCall)


class RetrieveRecords(ApiFollower):
    """This is tricky.  The API lets you take slices of data, but you only know the indices to use in the call from the previously taken slices.  Further, to get actual information for the records in a slice, you need another API call.  Here we see if the previous call worked, spawn the detail calls as needed, and either hit the API again or finish up, depending on whether we wanted any more records."""
    def run(self, urldata):
        try:
            if self.result['status'] == 1:
                self.spawnDetailCalls()
                if self.moreResultsLeft():
                    self.rebound()
                #Successful closeout
                else:
                    logger.info("Cleaning up")
                    self.cleanup()
                return True
            else:
                logger.error("Unhandled status: "+str(self.result['status']))
                return True
        except Exception, err:
            logger.error("ERROR!:{0}".format(err))
            return False

    def rebound(self):
        self.api_context.start_at_record_id = self.result['information'][-1]['id']
        ac = ApiCall()
        rr = RetrieveRecords()
        pass_context = deepcopy(self.api_context)
        chain(ac.s(mode='&lt;mode&gt;',api_context=pass_context), rr.s()).delay()

    def cleanup(self):
        &lt;do stuff&gt;

    def spawnDetailCalls(self):
        for result in self.result['information']:
            ac = ApiCall()
            ud = UploadData()
            self.api_context.record_id=result['record_id']
            self.api_context.processed+=1
            pass_context = deepcopy(self.api_context)
            chain(ac.s(mode='&lt;mode&gt;',api_context=pass_context), ud.s()).delay()

    def moreResultsLeft(self):
        if self.result['results_remaining'] == 0:
            return False
        elif self.api_context.processed &gt;= self.api_context.records_desired:
            return False
        else:
            if self.api_context.deepcopy is False:
                return self.api_context.last_scrape_time &lt; self.result['information'][-1]['start_time']
            else:
                return True
tasks.register(RetrieveRecords)
</code></pre></div>
<h1 dir="auto">Checklist</h1>

<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have verified that the issue exists against the <code class="notranslate">master</code> branch of Celery.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> This has already been asked to the <a href="https://groups.google.com/forum/#!forum/celery-users" rel="nofollow">discussion group</a> first.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have read the relevant section in the<br>
<a href="http://docs.celeryproject.org/en/latest/contributing.html#other-bugs" rel="nofollow">contribution guide</a><br>
on reporting bugs.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the <a href="https://github.com/celery/celery/issues?q=is%3Aissue+label%3A%22Issue+Type%3A+Bug+Report%22+-label%3A%22Category%3A+Documentation%22">issues list</a><br>
for similar or identical bug reports.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the <a href="https://github.com/celery/celery/pulls?q=is%3Apr+label%3A%22PR+Type%3A+Bugfix%22+-label%3A%22Category%3A+Documentation%22">pull requests list</a><br>
for existing proposed fixes.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the <a href="https://github.com/celery/celery/commits/master">commit log</a><br>
to find out if the bug was already fixed in the master branch.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have included all related issues and possible duplicate issues<br>
in this issue (If there are none, check this box anyway).</li>
</ul>
<h2 dir="auto">Mandatory Debugging Information</h2>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have included the output of <code class="notranslate">celery -A proj report</code> in the issue.<br>
(if you are not able to do this, then at least specify the Celery<br>
version affected).</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have verified that the issue exists against the <code class="notranslate">master</code> branch of Celery.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have included the contents of <code class="notranslate">pip freeze</code> in the issue.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have included all the versions of all the external dependencies required<br>
to reproduce this bug.</li>
</ul>
<h2 dir="auto">Optional Debugging Information</h2>

<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have tried reproducing the issue on more than one Python version<br>
and/or implementation.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue on more than one message broker and/or<br>
result backend.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue on more than one version of the message<br>
broker and/or result backend.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue on more than one operating system.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue on more than one workers pool.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue with autoscaling, retries,<br>
ETA/Countdown &amp; rate limits disabled.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have tried reproducing the issue after downgrading<br>
and/or upgrading Celery and its dependencies.</li>
</ul>
<h2 dir="auto">Related Issues and Possible Duplicates</h2>

<h4 dir="auto">Related Issues</h4>
<ul dir="auto">
<li>None</li>
</ul>
<h4 dir="auto">Possible Duplicates</h4>
<ul dir="auto">
<li>None</li>
</ul>
<h2 dir="auto">Environment &amp; Settings</h2>

<p dir="auto"><strong>Celery version</strong>:<br>
5.1.0 (sun-harmonics)</p>

<details>
<summary><b><code class="notranslate">celery report</code> Output:</b></summary>
<p dir="auto">
</p><div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=""><pre class="notranslate"><code class="notranslate"></code></pre></div>
<p dir="auto"></p>
</details>
<h1 dir="auto">Steps to Reproduce</h1>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="In [1]: from celery.utils.functional import regen
In [2]: from collections import deque
In [3]: l = regen(deque([1]))
In [4]: l
Out[4]: [1]
In [5]: l
Out[5]: [1, 1]
In [6]: l
Out[6]: [1, 1, 1]"><pre class="notranslate"><span class="pl-v">In</span> [<span class="pl-c1">1</span>]: <span class="pl-s1">from</span> <span class="pl-s1">celery</span>.<span class="pl-s1">utils</span>.<span class="pl-s1">functional</span> <span class="pl-s1">import</span> <span class="pl-s1">regen</span>
<span class="pl-v">In</span> [<span class="pl-c1">2</span>]: <span class="pl-s1">from</span> <span class="pl-s1">collections</span> <span class="pl-k">import</span> <span class="pl-s1">deque</span>
<span class="pl-v">In</span> [<span class="pl-c1">3</span>]: <span class="pl-s1">l</span> <span class="pl-c1">=</span> <span class="pl-en">regen</span>(<span class="pl-en">deque</span>([<span class="pl-c1">1</span>]))
<span class="pl-v">In</span> [<span class="pl-c1">4</span>]: <span class="pl-s1">l</span>
<span class="pl-v">Out</span>[<span class="pl-c1">4</span>]: [<span class="pl-c1">1</span>]
<span class="pl-v">In</span> [<span class="pl-c1">5</span>]: <span class="pl-s1">l</span>
<span class="pl-v">Out</span>[<span class="pl-c1">5</span>]: [<span class="pl-c1">1</span>, <span class="pl-c1">1</span>]
<span class="pl-v">In</span> [<span class="pl-c1">6</span>]: <span class="pl-s1">l</span>
<span class="pl-v">Out</span>[<span class="pl-c1">6</span>]: [<span class="pl-c1">1</span>, <span class="pl-c1">1</span>, <span class="pl-c1">1</span>]</pre></div>
<p dir="auto">When using <code class="notranslate">.map()</code> with non-list, non-tuple sequence passed all the items are processed 3 times:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@shared_task
def print_task(i):
    print(i)

# Print out 42 three times, can also use Django Queryset or any other Sequence
print_task.map(deque([42])).delay()"><pre class="notranslate"><span class="pl-en">@<span class="pl-s1">shared_task</span></span>
<span class="pl-k">def</span> <span class="pl-en">print_task</span>(<span class="pl-s1">i</span>):
    <span class="pl-en">print</span>(<span class="pl-s1">i</span>)

<span class="pl-c"># Print out 42 three times, can also use Django Queryset or any other Sequence</span>
<span class="pl-s1">print_task</span>.<span class="pl-en">map</span>(<span class="pl-en">deque</span>([<span class="pl-c1">42</span>])).<span class="pl-en">delay</span>()</pre></div>
<h2 dir="auto">Required Dependencies</h2>
<p dir="auto">No dependencies</p>

<ul dir="auto">
<li><strong>Minimal Python Version</strong>: checked 3.8.2 and 3.9.0+</li>
<li><strong>Minimal Celery Version</strong>: checked 4.4.2, 4.4.7 and 5.10</li>
<li><strong>Minimal Kombu Version</strong>: N/A or Unknown</li>
<li><strong>Minimal Broker Version</strong>: N/A or Unknown</li>
<li><strong>Minimal Result Backend Version</strong>: N/A or Unknown</li>
<li><strong>Minimal OS and/or Kernel Version</strong>: N/A or Unknown</li>
<li><strong>Minimal Broker Client Version</strong>: N/A or Unknown</li>
<li><strong>Minimal Result Backend Client Version</strong>: N/A or Unknown</li>
</ul>
<h3 dir="auto">Python Packages</h3>

<details>
<summary><b><code class="notranslate">pip freeze</code> Output:</b></summary>
<p dir="auto">
</p><div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="amqp==5.0.6
backcall==0.2.0
billiard==3.6.4.0
-e git+git@github.com:celery/celery.git@025bad6e93087414b3ddc288060c367d1937774b#egg=celery
click==7.1.2
click-didyoumean==0.0.3
click-plugins==1.1.1
click-repl==0.1.6
decorator==5.0.9
ipython==7.23.1
ipython-genutils==0.2.0
jedi==0.18.0
kombu==5.1.0
matplotlib-inline==0.1.2
parso==0.8.2
pexpect==4.8.0
pickleshare==0.7.5
prompt-toolkit==3.0.18
ptyprocess==0.7.0
Pygments==2.9.0
pytz==2021.1
six==1.16.0
traitlets==5.0.5
vine==5.0.0
wcwidth==0.2.5"><pre class="notranslate"><code class="notranslate">amqp==5.0.6
backcall==0.2.0
billiard==3.6.4.0
-e git+git@github.com:celery/celery.git@025bad6e93087414b3ddc288060c367d1937774b#egg=celery
click==7.1.2
click-didyoumean==0.0.3
click-plugins==1.1.1
click-repl==0.1.6
decorator==5.0.9
ipython==7.23.1
ipython-genutils==0.2.0
jedi==0.18.0
kombu==5.1.0
matplotlib-inline==0.1.2
parso==0.8.2
pexpect==4.8.0
pickleshare==0.7.5
prompt-toolkit==3.0.18
ptyprocess==0.7.0
Pygments==2.9.0
pytz==2021.1
six==1.16.0
traitlets==5.0.5
vine==5.0.0
wcwidth==0.2.5
</code></pre></div>
<p dir="auto"></p>
</details>
<h3 dir="auto">Other Dependencies</h3>

<details>
<p dir="auto">
N/A
</p>
</details>
<h2 dir="auto">Minimally Reproducible Test Case</h2>

<details>
<p dir="auto">
</p><div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="In [1]: from celery.utils.functional import regen
In [2]: from collections import deque
In [3]: l = regen(deque([1]))
In [4]: l
Out[4]: [1]
In [5]: l
Out[5]: [1, 1]
In [6]: l
Out[6]: [1, 1, 1]"><pre class="notranslate"><span class="pl-v">In</span> [<span class="pl-c1">1</span>]: <span class="pl-s1">from</span> <span class="pl-s1">celery</span>.<span class="pl-s1">utils</span>.<span class="pl-s1">functional</span> <span class="pl-s1">import</span> <span class="pl-s1">regen</span>
<span class="pl-v">In</span> [<span class="pl-c1">2</span>]: <span class="pl-s1">from</span> <span class="pl-s1">collections</span> <span class="pl-k">import</span> <span class="pl-s1">deque</span>
<span class="pl-v">In</span> [<span class="pl-c1">3</span>]: <span class="pl-s1">l</span> <span class="pl-c1">=</span> <span class="pl-en">regen</span>(<span class="pl-en">deque</span>([<span class="pl-c1">1</span>]))
<span class="pl-v">In</span> [<span class="pl-c1">4</span>]: <span class="pl-s1">l</span>
<span class="pl-v">Out</span>[<span class="pl-c1">4</span>]: [<span class="pl-c1">1</span>]
<span class="pl-v">In</span> [<span class="pl-c1">5</span>]: <span class="pl-s1">l</span>
<span class="pl-v">Out</span>[<span class="pl-c1">5</span>]: [<span class="pl-c1">1</span>, <span class="pl-c1">1</span>]
<span class="pl-v">In</span> [<span class="pl-c1">6</span>]: <span class="pl-s1">l</span>
<span class="pl-v">Out</span>[<span class="pl-c1">6</span>]: [<span class="pl-c1">1</span>, <span class="pl-c1">1</span>, <span class="pl-c1">1</span>]</pre></div>
<p dir="auto"></p>
</details>
<h1 dir="auto">Expected Behavior</h1>

<p dir="auto">Expected for <code class="notranslate">regen()</code> to not duplicate entires and for <code class="notranslate">.map()</code> to run each item once.</p>
<h1 dir="auto">Actual Behavior</h1>

<p dir="auto">See above.</p>