Repository: celery/celery

Issue:
Prepend to sys.path in the Django fixup instead of appending.
This makes sure that project modules have precedence over system ones.
Closes #5347.

## Description

This follows @Phyks's suggestion of a fix for #5347, by prepending instead of appending to the system path, to ensure that the project modules are not hidden by system-wide ones.



Discussion:
# [Codecov](https://codecov.io/gh/celery/celery/pull/5355?src=pr&el=h1) Report
> Merging [#5355](https://codecov.io/gh/celery/celery/pull/5355?src=pr&el=desc) into [master](https://codecov.io/gh/celery/celery/commit/210ad35e8c8a0ed26abbec45126700eebec1d0ef?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/celery/celery/pull/5355/graphs/tree.svg?width=650&token=hOkjyacuU9&height=150&src=pr)](https://codecov.io/gh/celery/celery/pull/5355?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #5355   +/-   ##
=======================================
  Coverage   83.37%   83.37%           
=======================================
  Files         144      144           
  Lines       16450    16450           
  Branches     2047     2047           
=======================================
  Hits        13716    13716           
  Misses       2527     2527           
  Partials      207      207
```


| [Impacted Files](https://codecov.io/gh/celery/celery/pull/5355?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [celery/fixups/django.py](https://codecov.io/gh/celery/celery/pull/5355/diff?src=pr&el=tree#diff-Y2VsZXJ5L2ZpeHVwcy9kamFuZ28ucHk=) | `93.07% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/celery/celery/pull/5355?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/celery/celery/pull/5355?src=pr&el=footer). Last update [210ad35...d235558](https://codecov.io/gh/celery/celery/pull/5355?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

Thank you a million @auvipy!
welcome 2 million :) @wetneb 
I don't think this is correct, Python lists don't have a `prepend` method. Was this tested?

Usually to add something as the first element you would use:
```python
sys.path.insert(0, os.getcwd())
```

This was reported by a user on IRC:
```
AttributeError: 'list' object has no attribute 'prepend'
```

@auvipy I'd suggest we back this out.
Oops, sorry about that! That's a pretty epic fail on my part.

Resolving patch:
diff --git a/celery/fixups/django.py b/celery/fixups/django.py
--- a/celery/fixups/django.py
+++ b/celery/fixups/django.py
@@ -60,7 +60,7 @@ def install(self):
         # Need to add project directory to path.
         # The project directory has precedence over system modules,
         # so we prepend it to the path.
-        sys.path.prepend(os.getcwd())
+        sys.path.insert(0, os.getcwd())
 
         self._settings = symbol_by_name('django.conf:settings')
         self.app.loader.now = self.now


Test patch:
diff --git a/t/unit/fixups/test_django.py b/t/unit/fixups/test_django.py
--- a/t/unit/fixups/test_django.py
+++ b/t/unit/fixups/test_django.py
@@ -91,7 +91,7 @@ def test_install(self, patching):
             f.install()
             self.sigs.worker_init.connect.assert_called_with(f.on_worker_init)
             assert self.app.loader.now == f.now
-            self.p.prepend.assert_called_with('/opt/vandelay')
+            self.p.insert.assert_called_with(0, '/opt/vandelay')
 
     def test_now(self):
         with self.fixup_context(self.app) as (f, _, _):