@@ -2872,6 +2872,13 @@ def check_warning(self, code, errtext, filename="<testcase>", mode="exec"):
28722872 with self .assertWarnsRegex (SyntaxWarning , errtext ):
28732873 compile (code , filename , mode )
28742874
2875+ def check_no_warning (self , code , filename = "<testcase>" , mode = "exec" ):
2876+ """Check that compiling code does not raise any warnings."""
2877+ with warnings .catch_warnings (record = True ) as caught :
2878+ warnings .simplefilter ("always" )
2879+ compile (source , filename , mode )
2880+ self .assertEqual (caught , [])
2881+
28752882 def test_return_in_finally (self ):
28762883 source = textwrap .dedent ("""
28772884 def f():
@@ -2942,6 +2949,74 @@ def test_break_and_continue_in_finally(self):
29422949 """ )
29432950 self .check_warning (source , f"'{ kw } ' in a 'finally' block" )
29442951
2952+ def test_from_lazy_imports (self ):
2953+ # gh-150459
2954+ self .check_warning (
2955+ "from . lazy import x" ,
2956+ "did you mean 'lazy from . import'?" ,
2957+ )
2958+ self .check_warning (
2959+ "from . lazy import x as y" ,
2960+ "did you mean 'lazy from . import'?" ,
2961+ )
2962+ self .check_warning (
2963+ "from . lazy import *" ,
2964+ "did you mean 'lazy from . import'?" ,
2965+ )
2966+ self .check_warning (
2967+ "from .. lazy import x" ,
2968+ "did you mean 'lazy from .. import'?" ,
2969+ )
2970+ self .check_warning (
2971+ "from ... lazy import x" ,
2972+ "did you mean 'lazy from ... import'?" ,
2973+ )
2974+ self .check_warning (
2975+ "from .... lazy import x" ,
2976+ "did you mean 'lazy from .... import'?" ,
2977+ )
2978+ self .check_warning (
2979+ "from . \\ \n lazy import x" ,
2980+ "did you mean 'lazy from . import'?" ,
2981+ )
2982+ self .check_warning (
2983+ "from .\\ \n lazy import x" ,
2984+ "did you mean 'lazy from . import'?" ,
2985+ )
2986+ self .check_warning (
2987+ "from .\t lazy import x" ,
2988+ "did you mean 'lazy from . import'?" ,
2989+ )
2990+
2991+ def test_not_from_lazy_imports (self ):
2992+ self .check_no_warning ("from .lazy import x" )
2993+ self .check_no_warning ("from .lazy import *" )
2994+ self .check_no_warning ("from ..lazy import x" )
2995+ self .check_no_warning ("from ...lazy import x" )
2996+ self .check_no_warning ("from .lazy.sub import x" )
2997+ self .check_no_warning ("from ..lazy.sub import x" )
2998+ self .check_no_warning ("from ...lazy.sub import x" )
2999+ self .check_no_warning ("from . lazier import x" )
3000+ self .check_no_warning ("from . lazy_module import x" )
3001+ self .check_no_warning ("from . lazy.sub import x" )
3002+ self .check_no_warning ("from . sub.lazy import x" )
3003+ self .check_no_warning ("from lazy import x" )
3004+ self .check_no_warning ("from lazy.sub import x" )
3005+ self .check_no_warning ("lazy from . lazy import x" )
3006+ self .check_no_warning ("from . import lazy" )
3007+
3008+ def test_from_lazy_imports_as_error (self ):
3009+ with warnings .catch_warnings ():
3010+ warnings .simplefilter ("error" , SyntaxWarning )
3011+ with self .assertRaisesRegex (
3012+ SyntaxError ,
3013+ re .escape ("did you mean 'lazy from . import'?" ),
3014+ ) as cm :
3015+ compile ("from . lazy import x" , "<test>" , "exec" )
3016+ self .assertEqual (cm .exception .lineno , 1 )
3017+ self .assertEqual (cm .exception .offset , 8 )
3018+ self .assertEqual (cm .exception .end_offset , 12 )
3019+
29453020
29463021class SyntaxErrorTestCase (unittest .TestCase ):
29473022
@@ -3620,6 +3695,18 @@ def inner():
36203695
36213696 self ._check_error ("""\
36223697 from os lazy import path
3698+ """ , "use 'lazy from ... ' instead of 'from ... lazy import'" )
3699+ self ._check_error ("""\
3700+ from os.path lazy import join
3701+ """ , "use 'lazy from ... ' instead of 'from ... lazy import'" )
3702+ self ._check_error ("""\
3703+ from .mod lazy import join
3704+ """ , "use 'lazy from ... ' instead of 'from ... lazy import'" )
3705+ self ._check_error ("""\
3706+ from ..mod lazy import join
3707+ """ , "use 'lazy from ... ' instead of 'from ... lazy import'" )
3708+ self ._check_error ("""\
3709+ from ...mod lazy import join
36233710""" , "use 'lazy from ... ' instead of 'from ... lazy import'" )
36243711
36253712 def test_lazy_import_valid_cases (self ):
0 commit comments