Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
e28bb150
Commit
e28bb150
authored
Nov 23, 2013
by
Michael Foord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue 17457: extend test discovery to support namespace packages
parent
8933521b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
150 additions
and
11 deletions
+150
-11
Lib/unittest/loader.py
Lib/unittest/loader.py
+51
-9
Lib/unittest/test/test_discovery.py
Lib/unittest/test/test_discovery.py
+78
-2
Misc/NEWS
Misc/NEWS
+3
-0
Misc/python-wing5.wpr
Misc/python-wing5.wpr
+18
-0
No files found.
Lib/unittest/loader.py
View file @
e28bb150
...
...
@@ -61,8 +61,9 @@ class TestLoader(object):
def
loadTestsFromTestCase
(
self
,
testCaseClass
):
"""Return a suite of all tests cases contained in testCaseClass"""
if
issubclass
(
testCaseClass
,
suite
.
TestSuite
):
raise
TypeError
(
"Test cases should not be derived from TestSuite."
\
" Maybe you meant to derive from TestCase?"
)
raise
TypeError
(
"Test cases should not be derived from "
"TestSuite. Maybe you meant to derive from "
"TestCase?"
)
testCaseNames
=
self
.
getTestCaseNames
(
testCaseClass
)
if
not
testCaseNames
and
hasattr
(
testCaseClass
,
'runTest'
):
testCaseNames
=
[
'runTest'
]
...
...
@@ -200,6 +201,8 @@ class TestLoader(object):
self
.
_top_level_dir
=
top_level_dir
is_not_importable
=
False
is_namespace
=
False
tests
=
[]
if
os
.
path
.
isdir
(
os
.
path
.
abspath
(
start_dir
)):
start_dir
=
os
.
path
.
abspath
(
start_dir
)
if
start_dir
!=
top_level_dir
:
...
...
@@ -213,15 +216,52 @@ class TestLoader(object):
else
:
the_module
=
sys
.
modules
[
start_dir
]
top_part
=
start_dir
.
split
(
'.'
)[
0
]
start_dir
=
os
.
path
.
abspath
(
os
.
path
.
dirname
((
the_module
.
__file__
)))
try
:
start_dir
=
os
.
path
.
abspath
(
os
.
path
.
dirname
((
the_module
.
__file__
)))
except
AttributeError
:
# look for namespace packages
try
:
spec
=
the_module
.
__spec__
except
AttributeError
:
spec
=
None
if
spec
and
spec
.
loader
is
None
:
if
spec
.
submodule_search_locations
is
not
None
:
is_namespace
=
True
for
path
in
the_module
.
__path__
:
if
(
not
set_implicit_top
and
not
path
.
startswith
(
top_level_dir
)):
continue
self
.
_top_level_dir
=
\
(
path
.
split
(
the_module
.
__name__
.
replace
(
"."
,
os
.
path
.
sep
))[
0
])
tests
.
extend
(
self
.
_find_tests
(
path
,
pattern
,
namespace
=
True
))
elif
the_module
.
__name__
in
sys
.
builtin_module_names
:
# builtin module
raise
TypeError
(
'Can not use builtin modules '
'as dotted module names'
)
from
None
else
:
raise
TypeError
(
'don
\
'
t know how to discover from {!r}'
.
format
(
the_module
))
from
None
if
set_implicit_top
:
self
.
_top_level_dir
=
self
.
_get_directory_containing_module
(
top_part
)
sys
.
path
.
remove
(
top_level_dir
)
if
not
is_namespace
:
self
.
_top_level_dir
=
\
self
.
_get_directory_containing_module
(
top_part
)
sys
.
path
.
remove
(
top_level_dir
)
else
:
sys
.
path
.
remove
(
top_level_dir
)
if
is_not_importable
:
raise
ImportError
(
'Start directory is not importable: %r'
%
start_dir
)
tests
=
list
(
self
.
_find_tests
(
start_dir
,
pattern
))
if
not
is_namespace
:
tests
=
list
(
self
.
_find_tests
(
start_dir
,
pattern
))
return
self
.
suiteClass
(
tests
)
def
_get_directory_containing_module
(
self
,
module_name
):
...
...
@@ -254,7 +294,7 @@ class TestLoader(object):
# override this method to use alternative matching strategy
return
fnmatch
(
path
,
pattern
)
def
_find_tests
(
self
,
start_dir
,
pattern
):
def
_find_tests
(
self
,
start_dir
,
pattern
,
namespace
=
False
):
"""Used by discovery. Yields test suites it loads."""
paths
=
sorted
(
os
.
listdir
(
start_dir
))
...
...
@@ -287,7 +327,8 @@ class TestLoader(object):
raise
ImportError
(
msg
%
(
mod_name
,
module_dir
,
expected_dir
))
yield
self
.
loadTestsFromModule
(
module
)
elif
os
.
path
.
isdir
(
full_path
):
if
not
os
.
path
.
isfile
(
os
.
path
.
join
(
full_path
,
'__init__.py'
)):
if
(
not
namespace
and
not
os
.
path
.
isfile
(
os
.
path
.
join
(
full_path
,
'__init__.py'
))):
continue
load_tests
=
None
...
...
@@ -304,7 +345,8 @@ class TestLoader(object):
# tests loaded from package file
yield
tests
# recurse into the package
yield
from
self
.
_find_tests
(
full_path
,
pattern
)
yield
from
self
.
_find_tests
(
full_path
,
pattern
,
namespace
=
namespace
)
else
:
try
:
yield
load_tests
(
self
,
tests
,
pattern
)
...
...
Lib/unittest/test/test_discovery.py
View file @
e28bb150
import
os
import
re
import
sys
import
types
import
builtins
from
test
import
support
import
unittest
...
...
@@ -173,7 +175,7 @@ class TestDiscovery(unittest.TestCase):
self
.
addCleanup
(
restore_isdir
)
_find_tests_args
=
[]
def
_find_tests
(
start_dir
,
pattern
):
def
_find_tests
(
start_dir
,
pattern
,
namespace
=
None
):
_find_tests_args
.
append
((
start_dir
,
pattern
))
return
[
'tests'
]
loader
.
_find_tests
=
_find_tests
...
...
@@ -436,7 +438,7 @@ class TestDiscovery(unittest.TestCase):
expectedPath
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
unittest
.
test
.
__file__
))
self
.
wasRun
=
False
def
_find_tests
(
start_dir
,
pattern
):
def
_find_tests
(
start_dir
,
pattern
,
namespace
=
None
):
self
.
wasRun
=
True
self
.
assertEqual
(
start_dir
,
expectedPath
)
return
tests
...
...
@@ -446,5 +448,79 @@ class TestDiscovery(unittest.TestCase):
self
.
assertEqual
(
suite
.
_tests
,
tests
)
def
test_discovery_from_dotted_path_builtin_modules
(
self
):
loader
=
unittest
.
TestLoader
()
listdir
=
os
.
listdir
os
.
listdir
=
lambda
_
:
[
'test_this_does_not_exist.py'
]
isfile
=
os
.
path
.
isfile
isdir
=
os
.
path
.
isdir
os
.
path
.
isdir
=
lambda
_
:
False
orig_sys_path
=
sys
.
path
[:]
def
restore
():
os
.
path
.
isfile
=
isfile
os
.
path
.
isdir
=
isdir
os
.
listdir
=
listdir
sys
.
path
[:]
=
orig_sys_path
self
.
addCleanup
(
restore
)
with
self
.
assertRaises
(
TypeError
)
as
cm
:
loader
.
discover
(
'sys'
)
self
.
assertEqual
(
str
(
cm
.
exception
),
'Can not use builtin modules '
'as dotted module names'
)
def
test_discovery_from_dotted_namespace_packages
(
self
):
loader
=
unittest
.
TestLoader
()
orig_import
=
__import__
package
=
types
.
ModuleType
(
'package'
)
package
.
__path__
=
[
'/a'
,
'/b'
]
package
.
__spec__
=
types
.
SimpleNamespace
(
loader
=
None
,
submodule_search_locations
=
[
'/a'
,
'/b'
]
)
def
_import
(
packagename
,
*
args
,
**
kwargs
):
sys
.
modules
[
packagename
]
=
package
return
package
def
cleanup
():
builtins
.
__import__
=
orig_import
self
.
addCleanup
(
cleanup
)
builtins
.
__import__
=
_import
_find_tests_args
=
[]
def
_find_tests
(
start_dir
,
pattern
,
namespace
=
None
):
_find_tests_args
.
append
((
start_dir
,
pattern
))
return
[
'%s/tests'
%
start_dir
]
loader
.
_find_tests
=
_find_tests
loader
.
suiteClass
=
list
suite
=
loader
.
discover
(
'package'
)
self
.
assertEqual
(
suite
,
[
'/a/tests'
,
'/b/tests'
])
def
test_discovery_failed_discovery
(
self
):
loader
=
unittest
.
TestLoader
()
package
=
types
.
ModuleType
(
'package'
)
orig_import
=
__import__
def
_import
(
packagename
,
*
args
,
**
kwargs
):
sys
.
modules
[
packagename
]
=
package
return
package
def
cleanup
():
builtins
.
__import__
=
orig_import
self
.
addCleanup
(
cleanup
)
builtins
.
__import__
=
_import
with
self
.
assertRaises
(
TypeError
)
as
cm
:
loader
.
discover
(
'package'
)
self
.
assertEqual
(
str
(
cm
.
exception
),
'don
\
'
t know how to discover from {!r}'
.
format
(
package
))
if
__name__
==
'__main__'
:
unittest
.
main
()
Misc/NEWS
View file @
e28bb150
...
...
@@ -479,6 +479,9 @@ Core and Builtins
Library
-------
-
Issue
#
17457
:
unittest
test
discovery
now
works
with
namespace
packages
.
Patch
by
Claudiu
Popa
.
-
Issue
#
18235
:
Fix
the
sysconfig
variables
LDSHARED
and
BLDSHARED
under
AIX
.
Patch
by
David
Edelsohn
.
...
...
Misc/python-wing5.wpr
0 → 100644
View file @
e28bb150
#!wing
#!version=5.0
##################################################################
# Wing IDE project file #
##################################################################
[project attributes]
proj.directory-list = [{'dirloc': loc('..'),
'excludes': [u'.hg',
u'Lib/unittest/__pycache__',
u'Lib/unittest/test/__pycache__',
u'Lib/__pycache__',
u'build',
u'Doc/build'],
'filter': '*',
'include_hidden': False,
'recursive': True,
'watch_for_changes': True}]
proj.file-type = 'shared'
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment