Fix issue 3221 by emitting a RuntimeWarning instead of raising SystemError when the parent module can't be found during an absolute import (likely due to non-PEP 361 aware code which sets a module level __package__ attribute)
diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py
index ab6fc25..ed9c7af 100644
--- a/Lib/test/test_import.py
+++ b/Lib/test/test_import.py
@@ -1,5 +1,3 @@
-from test.test_support import TESTFN, run_unittest, catch_warning
-
 import unittest
 import os
 import random
@@ -7,7 +5,7 @@
 import sys
 import py_compile
 import warnings
-from test.test_support import unlink, TESTFN, unload
+from test.test_support import unlink, TESTFN, unload, run_unittest, catch_warning
 
 
 def remove_files(name):
@@ -266,6 +264,38 @@
         from . import relimport
         self.assertTrue(hasattr(relimport, "RelativeImport"))
 
+    def test_issue3221(self):
+        def check_absolute():
+            exec "from os import path" in ns
+        def check_relative():
+            exec "from . import relimport" in ns
+        # Check both OK with __package__ and __name__ correct
+        ns = dict(__package__='test', __name__='test.notarealmodule')
+        check_absolute()
+        check_relative()
+        # Check both OK with only __name__ wrong
+        ns = dict(__package__='test', __name__='notarealpkg.notarealmodule')
+        check_absolute()
+        check_relative()
+        # Check relative fails with only __package__ wrong
+        ns = dict(__package__='foo', __name__='test.notarealmodule')
+        with catch_warning() as w:
+            check_absolute()
+            self.assert_('foo' in str(w.message))
+            self.assertEqual(w.category, RuntimeWarning)
+        self.assertRaises(SystemError, check_relative)
+        # Check relative fails with __package__ and __name__ wrong
+        ns = dict(__package__='foo', __name__='notarealpkg.notarealmodule')
+        with catch_warning() as w:
+            check_absolute()
+            self.assert_('foo' in str(w.message))
+            self.assertEqual(w.category, RuntimeWarning)
+        self.assertRaises(SystemError, check_relative)
+        # Check both fail with package set to a non-string
+        ns = dict(__package__=object())
+        self.assertRaises(ValueError, check_absolute)
+        self.assertRaises(ValueError, check_relative)
+
 def test_main(verbose=None):
     run_unittest(ImportTest, PathsTests, RelativeImport)
 
diff --git a/Misc/NEWS b/Misc/NEWS
index 0cee84e..e29a9b0 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,12 @@
 Core and Builtins
 -----------------
 
+- Issue #3221: Issue a RuntimeWarning instead of raising SystemError if
+  the parent module cannot be found while performing an absolute import.
+  This means that an incorrectly defined __package__ attribute will
+  now only prevent relative imports in that module rather than causing
+  all imports from that module to fail.
+
 - Issue #2517: Allow unicode messages in Exceptions again by correctly
   bypassing the instance dictionary when looking up __unicode__ on
   new-style classes.
diff --git a/Python/import.c b/Python/import.c
index b65ed0e..f0ee40a 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -2160,6 +2160,7 @@
 	static PyObject *pathstr = NULL;
 	static PyObject *pkgstr = NULL;
 	PyObject *pkgname, *modname, *modpath, *modules, *parent;
+	int orig_level = level;
 
 	if (globals == NULL || !PyDict_Check(globals) || !level)
 		return Py_None;
@@ -2285,9 +2286,27 @@
 
 	modules = PyImport_GetModuleDict();
 	parent = PyDict_GetItemString(modules, buf);
-	if (parent == NULL)
-		PyErr_Format(PyExc_SystemError,
-				"Parent module '%.200s' not loaded", buf);
+	if (parent == NULL) {
+		if (orig_level < 1) {
+			PyObject *err_msg = PyString_FromFormat(
+				"Parent module '%.200s' not found "
+				"while handling absolute import", buf);
+			if (err_msg == NULL) {
+				return NULL;
+			}
+			if (!PyErr_WarnEx(PyExc_RuntimeWarning,
+					PyString_AsString(err_msg), 1)) {
+				*buf = '\0';
+				*p_buflen = 0;
+				parent = Py_None;
+			}
+			Py_DECREF(err_msg);
+		} else {
+			PyErr_Format(PyExc_SystemError,
+				"Parent module '%.200s' not loaded, "
+				"cannot perform relative import", buf);
+		}
+	}
 	return parent;
 	/* We expect, but can't guarantee, if parent != None, that:
 	   - parent.__name__ == buf