Edgewall Software

Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#13449 closed defect (fixed)

Exception: 'NameError: name 'reload' is not defined' when using mod_python with Python 3.x — at Version 3

Reported by: john.de.rooij@… Owned by: Jun Omae
Priority: normal Milestone: 1.5.4
Component: web frontend/mod_python Version: 1.5.3
Severity: blocker Keywords: patch
Cc: Branch:
Release Notes:

Fix use of reload() which has been removed in Python 3.0, when mod_python is used.

API Changes:
Internal Changes:

Description

When Trac 1.5.3 is used in combination with mod_python on an Apache2 server, together in combination with Python 3.9, a 'NameError: name 'reload' is not defined' exception is raised.

The reload function which was a builtin function in Python 2.x has moved to the imp module or the importlib module depending on the actually used Python 3.x version. Because this problem in present in the modpython_frontend.py it will only be present when mod_python is used. A 'tracd' installation will not show this problem.

This is also the only reload call that is present in the complete trac sourcecode.

The relevant python backtrace is:

PythonHandler trac.web.modpython_frontend: NameError: name 'reload' is not defined
PythonHandler trac.web.modpython_frontend: Traceback (most recent call last):
PythonHandler trac.web.modpython_frontend:   File "/usr/lib/python3/dist-packages/mod_python/apache.py", line 398, in HandlerDispatch\n    result = obj(req)
PythonHandler trac.web.modpython_frontend:   File "/usr/local/lib/python3.9/dist-packages/trac/web/modpython_frontend.py", line 146, in handler\n    reload(sys.modules['trac.web'])

A diff patch to resolve this problem is also attached.

Change History (4)

by john.de.rooij@…, 2 years ago

Attachment: mod_python_reload.diff added

Patch: Use reload from the correct module depending on the running Python version

comment:1 by Jun Omae, 2 years ago

Branch: trunk
Milestone: 1.5.4
Owner: set to Jun Omae
Status: newassigned

Thanks for the reporting. I missed that reload() has been removed in Python 3.0.

$ pyflakes trac/web/modpython_frontend.py
trac/web/modpython_frontend.py:146: undefined name 'reload'

We could use simply importlib.reload(), because Trac 1.5.3 requires Python 3.5+.

  • trac/web/modpython_frontend.py

    diff --git a/trac/web/modpython_frontend.py b/trac/web/modpython_frontend.py
    index afd6cbf21..ebe813126 100644
    a b  
    1616# Author: Christopher Lenz <cmlenz@gmx.de>
    1717#         Matthew Good <trac@matt-good.net>
    1818
     19import importlib
    1920import os
    2021import pkg_resources
    2122import sys
    def handler(req):  
    143144                egg_cache = req.subprocess_env.get('PYTHON_EGG_CACHE')
    144145            if egg_cache:
    145146                pkg_resources.set_extraction_path(egg_cache)
    146             reload(sys.modules['trac.web'])
     147            importlib.reload(sys.modules['trac.web'])
    147148    pkg_resources.require('Trac==%s' % VERSION)
    148149    gateway = ModPythonGateway(req, req.get_options())
    149150    from trac.web.main import dispatch_request

comment:2 by john.de.rooij@…, 2 years ago

Ok. I just wanted to provide a generic solution that works for every used Python version.

Because Python ≥ 3.5 is a requirement for Trac 1.5, it is indeed also ok, and simpler to use the changes you suggested.

Can you apply your diff on trunk?

comment:3 by Jun Omae, 2 years ago

Release Notes: modified (diff)
Resolution: fixed
Status: assignedclosed

Committed in [17571].

Note: See TracTickets for help on using tickets.