diff --git a/webware/ImportManager.py b/webware/ImportManager.py
index 107a15b..ee936a6 100644
--- a/webware/ImportManager.py
+++ b/webware/ImportManager.py
@@ -61,12 +61,10 @@ def getReloader(self):
print()
return reloader
- def moduleFromSpec(self, spec, name=None):
+ def moduleFromSpec(self, spec):
"""Load the module with the given module spec."""
if not spec or not isinstance(spec, ModuleSpec):
raise TypeError(f'Invalid spec: {spec!r}')
- if name and not isinstance(name, str):
- raise TypeError(f'Invalid name: {name!r}')
try:
module = module_from_spec(spec)
except Exception:
@@ -76,14 +74,11 @@ def moduleFromSpec(self, spec, name=None):
if spec.origin:
self.recordFile(spec.origin)
raise
- if name:
- spec.name = name
- module.__package__ = spec.parent
self.recordModule(module)
spec.loader.exec_module(module)
return module
- def findSpec(self, name, path):
+ def findSpec(self, name, path, fullModuleName=None):
"""Find the module spec for the given name at the given path."""
if not name or not isinstance(name, str):
raise TypeError(f'Invalid name: {name!r}')
@@ -106,6 +101,8 @@ def findSpec(self, name, path):
fileName = f'{name}.py'
filePath = join(path, fileName)
if isfile(filePath):
+ if fullModuleName:
+ name = fullModuleName
loader = SourceFileLoader(name, filePath)
return spec_from_file_location(name, filePath, loader=loader)
diff --git a/webware/ServletFactory.py b/webware/ServletFactory.py
index ade00dd..921766c 100644
--- a/webware/ServletFactory.py
+++ b/webware/ServletFactory.py
@@ -194,10 +194,10 @@ def _importModuleFromDirectory(
'# Auto-generated by Webware' + os.linesep)
except Exception:
print("Error: __init__.py file could not be created.")
- spec = self._imp.findSpec(moduleName, directory)
- module = self._imp.moduleFromSpec(spec, fullModuleName)
+ spec = self._imp.findSpec(moduleName, directory, fullModuleName)
+ module = self._imp.moduleFromSpec(spec)
module.__donotreload__ = self._reloadClasses
- sys.modules['fullModuleName'] = module
+ sys.modules[fullModuleName] = module
return module
def loadClass(self, transaction, path):
diff --git a/webware/Testing/ServletImport.py b/webware/Testing/ServletImport.py
new file mode 100644
index 0000000..b384360
--- /dev/null
+++ b/webware/Testing/ServletImport.py
@@ -0,0 +1,26 @@
+
+from Page import Page
+import sys
+
+mod_name = __name__ # we expect Testing.ServletImport
+
+class ServletImport(Page):
+ """Test of import details."""
+
+ def title(self):
+ return self.__doc__
+
+ def writeBody(self):
+ self.writeln('
Webware Servlet Import Test
')
+ self.writeln(f'{self.title()}
')
+ mod_name_from_class = ServletImport.__module__ # we expect Testing.ServletImport
+ mod_name_consistent = mod_name == mod_name_from_class # we expect True
+ servlet_in_sys_modules = mod_name in sys.modules # we expect True
+ servlet_file_watched = __file__ in self.transaction().application()._imp.fileList(update=False) # we expect True
+ self.writeln(
+ f"mod_name = {mod_name}
"
+ f"mod_name_from_class = {mod_name_from_class}
"
+ f"mod_name_consistent = {mod_name_consistent}
"
+ f"servlet_in_sys_modules = {servlet_in_sys_modules}
"
+ f"servlet_file_watched = {servlet_file_watched}
"
+ )
diff --git a/webware/Testing/TestCases.data b/webware/Testing/TestCases.data
index c952182..8af0d46 100644
--- a/webware/Testing/TestCases.data
+++ b/webware/Testing/TestCases.data
@@ -60,3 +60,6 @@
# If-Modified-Since
/Testing/TestIMS --> TestIMS passed
+
+# ServletImport
+/Testing/ServletImport --> Servlet imported as part of package
diff --git a/webware/Tests/TestEndToEnd/AppTest.py b/webware/Tests/TestEndToEnd/AppTest.py
index 489e357..ae13cb6 100644
--- a/webware/Tests/TestEndToEnd/AppTest.py
+++ b/webware/Tests/TestEndToEnd/AppTest.py
@@ -17,11 +17,13 @@ class AppTest:
settings = dict(
PrintConfigAtStartUp=False
)
+ bufferOutput = True # set to False if you want to run pdb inside a test to debug it.
@classmethod
def setUpClass(cls):
stdout, stderr = sys.stdout, sys.stderr
- sys.stdout = sys.stderr = StringIO()
+ if cls.bufferOutput:
+ sys.stdout = sys.stderr = StringIO()
cls.currentDir = getcwd()
import webware
webwareDir = webware.__path__[0]
@@ -35,43 +37,55 @@ def setUpClass(cls):
else:
error = None
finally:
- output = sys.stdout.getvalue().rstrip()
- sys.stdout, sys.stderr = stdout, stderr
+ if cls.bufferOutput:
+ output = sys.stdout.getvalue().rstrip()
+ sys.stdout, sys.stderr = stdout, stderr
+ else:
+ output = ''
if error:
raise RuntimeError(
'Error setting up application:\n' + error +
'\nOutput was:\n' + output)
- if (not output.startswith('Webware for Python')
- or 'Running in development mode' not in output
- or 'Loading context' not in output):
- raise AssertionError(
- 'Application was not properly started.'
- ' Output was:\n' + output)
+ if cls.bufferOutput:
+ if (not output.startswith('Webware for Python')
+ or 'Running in development mode' not in output
+ or 'Loading context' not in output):
+ raise AssertionError(
+ 'Application was not properly started.'
+ ' Output was:\n' + output)
@classmethod
def tearDownClass(cls):
stdout, stderr = sys.stdout, sys.stderr
- sys.stdout = sys.stderr = StringIO()
+ if cls.bufferOutput:
+ sys.stdout = sys.stderr = StringIO()
cls.app.shutDown()
- output = sys.stdout.getvalue().rstrip()
- sys.stdout, sys.stderr = stdout, stderr
+ if cls.bufferOutput:
+ output = sys.stdout.getvalue().rstrip()
+ sys.stdout, sys.stderr = stdout, stderr
+ else:
+ output = ''
chdir(cls.currentDir)
- if output != ('Application is shutting down...\n'
- 'Application has been successfully shutdown.'):
+ if cls.bufferOutput and output != ('Application is shutting down...\n'
+ 'Application has been successfully shutdown.'):
raise AssertionError(
'Application was not properly shut down. Output was:\n'
+ output)
def setUp(self):
self.stdout, self.stderr = sys.stdout, sys.stderr
- sys.stdout = sys.stderr = StringIO()
+ if self.bufferOutput:
+ sys.stdout = sys.stderr = StringIO()
def tearDown(self):
- self.output = sys.stdout.getvalue().rstrip()
- sys.stdout, sys.stderr = self.stdout, self.stderr
+ if self.bufferOutput:
+ self.output = sys.stdout.getvalue().rstrip()
+ sys.stdout, sys.stderr = self.stdout, self.stderr
+ else:
+ self.output = ''
def run(self, result=None):
result = super().run(result) # pylint: disable=no-member
- if not result.wasSuccessful() and self.output:
+ if not result.wasSuccessful() and self.bufferOutput and self.output:
print("Application output was:")
print(self.output)
diff --git a/webware/Tests/TestEndToEnd/TestAdmin.py b/webware/Tests/TestEndToEnd/TestAdmin.py
index 9bdbeac..42b526f 100644
--- a/webware/Tests/TestEndToEnd/TestAdmin.py
+++ b/webware/Tests/TestEndToEnd/TestAdmin.py
@@ -232,7 +232,14 @@ def testAppControl(self):
'Reload the selected Python modules. Be careful!',
' Admin.AdminPage
')
- r.form.get('reloads', index=0).checked = True
+
+ # things change, so don't hardcode the index of this checkbox.
+ for i, checkbox in enumerate(r.html.find_all('input', attrs={'name': 'reloads'})):
+ if checkbox.attrs['value'] == 'Admin.AdminPage':
+ break
+ else:
+ assert False, 'Did not find expected checkbox for Admin.AdminPage'
+ r.form.get('reloads', index=i).checked = True
r = r.form.submit('action', index=1)
self.assertEqual(r.status, '200 OK')
r.mustcontain(
diff --git a/webware/Tests/TestEndToEnd/TestTesting.py b/webware/Tests/TestEndToEnd/TestTesting.py
index e673722..8550f1f 100644
--- a/webware/Tests/TestEndToEnd/TestTesting.py
+++ b/webware/Tests/TestEndToEnd/TestTesting.py
@@ -258,6 +258,16 @@ def testCase17(self):
self.assertEqual(r.headers.get('Last-Modified'), lastMod)
self.assertEqual(len(r.body), size)
+ def testCase18(self):
+ url = self.getTestCaseUrl(18, 'Servlet imported as part of package')
+ r = self.testApp.get(url)
+ self.assertEqual(r.status, '200 OK')
+ r.mustcontain(
+ 'Test of import details.',
+ 'mod_name = Testing.ServletImport
',
+ 'mod_name_from_class = Testing.ServletImport
',
+ f"servlet_in_sys_modules = True
",
+ )
class TestTestingWithExtraPathInfo(TestTesting):