Code

Opened 7 months ago

Last modified 5 weeks ago

#21628 new Cleanup/optimization

Stop using the `imp` module

Reported by: aaugustin Owned by: nobody
Component: Core (Other) Version: master
Severity: Normal Keywords:
Cc: merb Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

It's deprecated in Python 3.4: http://docs.python.org/3.4/library/imp. Django uses it in a handful of files.

Notably, it calls imp.acquire_lock() and imp.release_lock() in AppCache.populate(). These functions don't have a replacement. I'm not sure how to deal with that, maybe call them only on Python < 3.4?

Attachments (0)

Change History (11)

comment:1 Changed 7 months ago by aaugustin

We'll most likely have to write some wrappers in django.utils.importlib to cover all Python versions.

comment:2 Changed 7 months ago by loic84

As @aaugustin pointed out in a github comment, we used to have normal reentrant threads locking instead of calling these functions and that caused deadlocks (#18251).

It seems the behavior of those functions changed in 3.3 as well, dunno if the change affected us:

"Changed in version 3.3: The locking scheme has changed to per-module locks for the most part. A global import lock is kept for some critical tasks, such as initializing the per-module locks."

FWIW the Python ticket where the deprecation was discussed: http://bugs.python.org/issue17177.

Last edited 7 months ago by loic84 (previous) (diff)

comment:3 Changed 7 months ago by merb

@aaugustin i think we could just ignore this issue.

Currently I tried: https://code.djangoproject.com/attachment/ticket/18251/threading_lock.tar.gz
On Python 2.7.5+ and on Python 3.3.2+ the issue never occured. Without calling imp.acquire_lock() or imp.release_lock()

Maybe the "test" itself is somehow not correct anymore.

But I think its due to the fact that we now (since the last commit https://github.com/django/django/compare/fe1389e911b0...4a56a93cc458) use https://pypi.python.org/pypi/importlib a backport of importlib for python 2.7 due to the fact that the next django version won't be compatible to python 2.6. So just remove imp and we are fine. (btw. imp.acquire_lock() does nothing when you are working on master)

Last edited 7 months ago by merb (previous) (diff)

comment:4 Changed 7 months ago by merb

  • Cc merb added

comment:5 Changed 6 months ago by Aymeric Augustin <aymeric.augustin@…>

In d674fe6dee16735dd2670243153326806b7e6cb0:

Used a regular lock for app registry population.

Since the app registry is always populated before the first request is
processed, the situation described in #18251 for the old app cache
cannot happen any more.

Refs #18251, #21628.

comment:6 Changed 6 months ago by aaugustin

The app registry no longer uses the import lock, but there's still 5 uses of imp.find_module, one of imp.load_module and one of imp.new_module.

comment:7 Changed 6 months ago by mjtamlyn

It's worth noting that imp.find_module is the only one of these which is used in the source code (4 times), the others are only used in tests. Two of the uses in the main codebase are in a function which needs rewriting as it's about the old sys.path hackery from the old project layout, and we've already decided we are willing to *maybe* break some stuff there. There's already a TODO to this effect.

The others are in module_loading and we will need to write a separate path for py3+

comment:8 Changed 6 months ago by Alex Gaynor <alex.gaynor@…>

In 9d487ae2a16d1efd501e65c78e6885c8cdcd4421:

Refs #21628 -- removed one usage of the imp module in the tests. It is deprecated in Python 3.4

comment:9 Changed 6 weeks ago by claudep

FWIW, the only remaining usage of imp is in django.utils.module_loading.module_has_submodule (+ in the corresponding test module, test_module_loading.py).

comment:10 Changed 5 weeks ago by Aymeric Augustin <aymeric.augustin@…>

In d7f1f316bcb21853597515a25e6e43639b9ed021:

Simplified module_has_submodule on Python >= 3.3.

Stopped using the imp module on Python >= 3.3. Refs #21628.

comment:11 Changed 5 weeks ago by aaugustin

Removing usage in the tests is quite difficult. I tried to use the replacements from importlib but I keep hitting infinite recursions.

In fact it's a bit difficult to figure out what matters in the test. They were introduced in #13464 but that ticket is short on details.

If I understand Python's deprecation policy correctly, the imp module won't be removed before Python 4. We could simply silence the deprecation warning.

The alternative would be to run these tests only under Python < 3.3. The implementation on Python >= 3.3 is drastically simpler and may not require as many tests.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as new
The owner will be changed from nobody to anonymous. Next status will be 'assigned'
as The resolution will be set. Next status will be 'closed'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.