<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 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" checked=""> 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"> 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" checked=""> 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 (I've looked, don't see any, probably to odd corner case)</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>: celery==4.3.0</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="Sorry, I don't have a celery project setup. The error is when using send_task (the worker and the queuer of the tasks doesn't share any code base)"><pre class="notranslate"><code class="notranslate">Sorry, I don't have a celery project setup. The error is when using send_task (the worker and the queuer of the tasks doesn't share any code base)
</code></pre></div>
<p dir="auto"></p>
</details>
<h1 dir="auto">Steps to Reproduce</h1>
<h2 dir="auto">Required Dependencies</h2>

<ul dir="auto">
<li><strong>Minimal Python Version</strong>: Unknown (I'm on 3.6.3)</li>
<li><strong>Minimal Celery Version</strong>: N/A or Unknown</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="alembic==1.1.0
amqp==2.5.1
billiard==3.6.1.0
blinker==1.4
cachetools==3.1.1
celery==4.3.0
certifi==2019.9.11
chardet==3.0.4
Click==7.0
debtcollector==1.22.0
Flask==1.0.2
Flask-Classful==0.13.1
Flask-JSON==0.3.0
Flask-Migrate==2.0.1
Flask-Script==2.0.6
Flask-SQLAlchemy==2.4.0
gcloud==0.18.3
google-api-core==1.14.2
google-api-python-client==1.7.9
google-auth==1.6.3
google-auth-httplib2==0.0.3
google-cloud-core==1.0.3
google-cloud-datastore==1.8.0
google-cloud-pubsub==1.0.0
google-cloud-storage==1.16.1
google-resumable-media==0.4.0
googleapis-common-protos==1.6.0
grpc-google-iam-v1==0.12.3
grpcio==1.9.1
gunicorn==19.6.0
httplib2==0.13.1
idna==2.8
importlib-metadata==0.22
itsdangerous==1.1.0
Jinja2==2.10.1
kombu==4.6.4
Mako==1.1.0
MarkupSafe==1.1.1
monotonic==1.5
more-itertools==7.2.0
oauth2client==4.0.0
pbr==5.4.3
protobuf==3.6.1
psycopg2==2.7.3.2
psycopg2-binary==2.8.3
pyasn1==0.4.7
pyasn1-modules==0.2.6
python-dateutil==2.8.0
python-editor==1.0.4
pytz==2019.2
PyYAML==3.12
ratelimitingfilter==0.5.dev1
raven==6.10.0
requests==2.22.0
rsa==4.0
six==1.11.0
SQLAlchemy==1.3.8
statsd==3.3.0
tenacity==3.4.0
uritemplate==3.0.0
urllib3==1.25.3
vine==1.3.0
Werkzeug==0.15.6
wrapt==1.11.2
zipp==0.6.0"><pre class="notranslate"><code class="notranslate">alembic==1.1.0
amqp==2.5.1
billiard==3.6.1.0
blinker==1.4
cachetools==3.1.1
celery==4.3.0
certifi==2019.9.11
chardet==3.0.4
Click==7.0
debtcollector==1.22.0
Flask==1.0.2
Flask-Classful==0.13.1
Flask-JSON==0.3.0
Flask-Migrate==2.0.1
Flask-Script==2.0.6
Flask-SQLAlchemy==2.4.0
gcloud==0.18.3
google-api-core==1.14.2
google-api-python-client==1.7.9
google-auth==1.6.3
google-auth-httplib2==0.0.3
google-cloud-core==1.0.3
google-cloud-datastore==1.8.0
google-cloud-pubsub==1.0.0
google-cloud-storage==1.16.1
google-resumable-media==0.4.0
googleapis-common-protos==1.6.0
grpc-google-iam-v1==0.12.3
grpcio==1.9.1
gunicorn==19.6.0
httplib2==0.13.1
idna==2.8
importlib-metadata==0.22
itsdangerous==1.1.0
Jinja2==2.10.1
kombu==4.6.4
Mako==1.1.0
MarkupSafe==1.1.1
monotonic==1.5
more-itertools==7.2.0
oauth2client==4.0.0
pbr==5.4.3
protobuf==3.6.1
psycopg2==2.7.3.2
psycopg2-binary==2.8.3
pyasn1==0.4.7
pyasn1-modules==0.2.6
python-dateutil==2.8.0
python-editor==1.0.4
pytz==2019.2
PyYAML==3.12
ratelimitingfilter==0.5.dev1
raven==6.10.0
requests==2.22.0
rsa==4.0
six==1.11.0
SQLAlchemy==1.3.8
statsd==3.3.0
tenacity==3.4.0
uritemplate==3.0.0
urllib3==1.25.3
vine==1.3.0
Werkzeug==0.15.6
wrapt==1.11.2
zipp==0.6.0
</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">
1. Setup an exchange with a blank routing key in Rabbitmq
</p><div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="celeryapp.send_task(&quot;task, [&quot;data&quot;],exchange=&quot;your_exchange&quot;,routing_key='',connection=conn)"><pre class="notranslate"><span class="pl-s1">celeryapp</span>.<span class="pl-en">send_task</span>(<span class="pl-s">"task, ["</span><span class="pl-s1">data</span><span class="pl-s">"],exchange="</span><span class="pl-s1">your_exchange</span>",<span class="pl-s1">routing_key</span><span class="pl-c1">=</span><span class="pl-s">''</span>,<span class="pl-s1">connection</span><span class="pl-c1">=</span><span class="pl-s1">conn</span>)</pre></div>
<p dir="auto"></p>
</details>
<h1 dir="auto">Expected Behavior</h1>

<p dir="auto">I would expect a message sent with an exchange and a blank (but not None) routing key to be sent using the exchange and the blank routing key.</p>
<h1 dir="auto">Actual Behavior</h1>

<p dir="auto">Background:<br>
Due to legacy reasons I'm not capable of changing the routing structure in RabbitMQ.</p>
<p dir="auto">Using a blank routing key, the message is sent to the default queue. The issue originates from <a href="https://github.com/celery/celery/blob/master/celery/app/amqp.py#L529">amqp.py</a>:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="            if (not exchange or not routing_key) and exchange_type == 'direct':
                exchange, routing_key = '', qname"><pre class="notranslate">            <span class="pl-k">if</span> (<span class="pl-c1">not</span> <span class="pl-s1">exchange</span> <span class="pl-c1">or</span> <span class="pl-c1">not</span> <span class="pl-s1">routing_key</span>) <span class="pl-c1">and</span> <span class="pl-s1">exchange_type</span> <span class="pl-c1">==</span> <span class="pl-s">'direct'</span>:
                <span class="pl-s1">exchange</span>, <span class="pl-s1">routing_key</span> <span class="pl-c1">=</span> <span class="pl-s">''</span>, <span class="pl-s1">qname</span></pre></div>
<p dir="auto">Using not discards the blank routing key.</p>
<p dir="auto">I am not too well versed on advanced routing, but if you want to I can try to create a pull request changing it to:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="            if (not exchange or routing_key is None) and exchange_type == 'direct':
                exchange, routing_key = '', qname"><pre class="notranslate">            <span class="pl-k">if</span> (<span class="pl-c1">not</span> <span class="pl-s1">exchange</span> <span class="pl-c1">or</span> <span class="pl-s1">routing_key</span> <span class="pl-c1">is</span> <span class="pl-c1">None</span>) <span class="pl-c1">and</span> <span class="pl-s1">exchange_type</span> <span class="pl-c1">==</span> <span class="pl-s">'direct'</span>:
                <span class="pl-s1">exchange</span>, <span class="pl-s1">routing_key</span> <span class="pl-c1">=</span> <span class="pl-s">''</span>, <span class="pl-s1">qname</span></pre></div>
<p dir="auto">As a quirky short term work around, you can do:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="celeryapp.send_task(
    &quot;task&quot;, 
    [&quot;data&quot;],
    exchange=&quot;your_exchange&quot;,
    routing_key='',
    exchange_type='anything_but_direct_here',
    connection=conn
)"><pre class="notranslate"><span class="pl-s1">celeryapp</span>.<span class="pl-en">send_task</span>(
    <span class="pl-s">"task"</span>, 
    [<span class="pl-s">"data"</span>],
    <span class="pl-s1">exchange</span><span class="pl-c1">=</span><span class="pl-s">"your_exchange"</span>,
    <span class="pl-s1">routing_key</span><span class="pl-c1">=</span><span class="pl-s">''</span>,
    <span class="pl-s1">exchange_type</span><span class="pl-c1">=</span><span class="pl-s">'anything_but_direct_here'</span>,
    <span class="pl-s1">connection</span><span class="pl-c1">=</span><span class="pl-s1">conn</span>
)</pre></div>
<p dir="auto">Which won't trigger the offending if-bransch.</p>
<p dir="auto">I'm mostly creating this ticket so future Googlers can find it if they have the same problem. If you would accept a PR let me know.</p>
<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" checked=""> 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>
<p dir="auto">Hey there! I've read all the checkboxes etc. but it's such an obvious bug, that I feel they are not necessary. I hope that this unconformity won't let you just ignore the actual issue:</p>
<h1 dir="auto">Steps to Reproduce</h1>
<h2 dir="auto">Minimally Reproducible Test Case</h2>
<p dir="auto">Run celery on Windows, no matter which python.</p>
<h3 dir="auto">Expected Behavior</h3>
<p dir="auto">It should start</p>
<h3 dir="auto">Actual Behavior</h3>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  File &quot;.venv\lib\site-packages\celery\platforms.py&quot;, line 9, in &lt;module&gt;
    import grp
ModuleNotFoundError: No module named 'grp'"><pre class="notranslate"><code class="notranslate">  File ".venv\lib\site-packages\celery\platforms.py", line 9, in &lt;module&gt;
    import grp
ModuleNotFoundError: No module named 'grp'
</code></pre></div>
<p dir="auto">The module <code class="notranslate">grp</code> is only available on linux, thus this does not work on widnwos and also not make sense as a global import. It's also imported below by <code class="notranslate">try_import</code>.</p>
<h3 dir="auto">Possible fix</h3>
<p dir="auto">This line should simply be removed, because below there is a <code class="notranslate">try_import</code> for this as well. Also in the <code class="notranslate">check_privileges</code>, the non-existence of <code class="notranslate">grp</code> should be checked. Unfortunately due to my companies restrictions I cannot submit a MR.</p>
<p dir="auto">Git blame shows <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/namloc2001/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/namloc2001">@namloc2001</a> and <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/thedrow/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/thedrow">@thedrow</a> for <a href="https://github.com/celery/celery/blob/ce567e31065e3361493ebb33a23e2f04c07cc371/celery/platforms.py#L9">this line which is still on master</a>.</p>
<p dir="auto">Thanks!</p>