File tree Expand file tree Collapse file tree 6 files changed +86
-5
lines changed Expand file tree Collapse file tree 6 files changed +86
-5
lines changed Original file line number Diff line number Diff line change 5
5
"./tests/__init__.py" : " tests/__init__.py" ,
6
6
"./tests/test_asyncmock.py" : " tests/test_asyncmock.py" ,
7
7
"./tests/test_mock.py" : " tests/test_mock.py" ,
8
- "./tests/test_patch.py" : " tests/test_patch.py"
8
+ "./tests/test_patch.py" : " tests/test_patch.py" ,
9
+ "./tests/test_resolve_target.py" : " tests/test_resolve_target.py" ,
10
+ "./tests/a_package/__init__.py" : " tests/a_package/__init__.py" ,
11
+ "./tests/a_package/a_module.py" : " tests/a_package/a_module.py"
9
12
}
10
13
}
Original file line number Diff line number Diff line change
1
+ """
2
+ A dummy module for testing purposes.
3
+ """
4
+
5
+ import random
6
+
7
+
8
+ class AClass :
9
+ """
10
+ A dummy class for testing.
11
+ """
12
+
13
+ def __init__ (self , a : int ):
14
+ self .a = a
15
+
16
+ def a_method (self , b ):
17
+ return self .a + b
18
+
19
+ def __repr__ (self ):
20
+ return f"AClass(a={ self .a } )"
21
+
22
+
23
+ def a_function (a , b ):
24
+ return a + b
25
+
26
+
27
+ def another_function (a , b ):
28
+ return random .randint (a , b )
Original file line number Diff line number Diff line change 2
2
Tests the patch decorator/context manager.
3
3
"""
4
4
5
+ import upytest
5
6
from umock import patch
6
7
7
8
9
+ @upytest .skip ("upytest does not support patching yet" )
8
10
def test_patch_decorator ():
9
11
"""
10
12
Tests the patch decorator.
Original file line number Diff line number Diff line change
1
+ """
2
+ Tests for the resolve_target function used to return a target Python object
3
+ from a target string.
4
+ """
5
+
6
+ import upytest
7
+ from umock import resolve_target
8
+
9
+
10
+ def test_resolve_target_no_colon ():
11
+ """
12
+ The target path is a dotted string without a colon pointing to a specific
13
+ object in the module.
14
+ """
15
+ target = "tests.a_package.a_module.AClass"
16
+ expected = "AClass"
17
+ actual = resolve_target (target )
18
+ assert actual .__name__ == expected
19
+
20
+
21
+ def test_resolve_target_with_colon ():
22
+ """
23
+ The target path is a dotted string with a colon pointing to a specific
24
+ object in the module.
25
+ """
26
+ target = "tests.a_package.a_module:AClass.a_method"
27
+ expected = "a_method"
28
+ actual = resolve_target (target )
29
+ assert actual .__name__ == expected
30
+
31
+
32
+ def test_resolve_target_with_object ():
33
+ """
34
+ If the target is already an object, return it as is.
35
+ """
36
+ target = "tests.a_package.a_module.AClass"
37
+ expected = resolve_target (target )
38
+ actual = resolve_target (expected )
39
+ assert actual is expected
40
+
41
+
42
+ def test_resolve_target_invalid_target ():
43
+ """
44
+ If the target path points to an invalid object, raise an AttributeError.
45
+ """
46
+ target = "tests.a_package.a_module:AClass.not_a_method"
47
+ with upytest .raises (AttributeError ):
48
+ resolve_target (target )
Original file line number Diff line number Diff line change @@ -358,15 +358,15 @@ def resolve_target(target):
358
358
"Inspired by" pkgutil.resolve_name in the CPython standard library (but
359
359
much simpler/naive).
360
360
361
- Will raise an ImportError if the target module cannot be resolved or an
362
- AttributeError if the attribute cannot be found.
361
+ Will raise an AttributeError if the target object cannot be resolved.
363
362
"""
364
363
if not isinstance (target , str ):
365
364
return target
366
365
if ":" in target :
367
366
# There is a colon - a one-step import is all that's needed.
368
367
module_name , attributes = target .split (":" )
369
- module = __import__ (module_name )
368
+ module_path = module_name .replace ("." , "/" )
369
+ module = __import__ (module_path )
370
370
parts = attributes .split ("." )
371
371
else :
372
372
# No colon - have to iterate to find the package boundary.
@@ -377,7 +377,7 @@ def resolve_target(target):
377
377
while parts :
378
378
# Traverse the parts of the target to find the package boundary.
379
379
p = parts [0 ]
380
- new_module_name = f"{ module_name } . { p } "
380
+ new_module_name = f"{ module_name } / { p } "
381
381
try :
382
382
module = __import__ (new_module_name )
383
383
parts .pop (0 )
You can’t perform that action at this time.
0 commit comments