def make_all_tests(cls): for path, module in modules.walk_modules(recursive=True, check_optional=False): if module.endswith(NON_APPLICABLE_SUFFIXES): continue test = make_exec_test(path, module) setattr(cls, test.__name__, test) return cls
def _create_tests(): for _, modname in modules.walk_modules(include_so=False, recursive=True, check_optional=False): if modname.endswith(PLATFORM_SPECIFIC_SUFFIXES): continue orig_modname = modname modname_no_period = orig_modname.replace('.', '_') cls = type('Test_' + modname_no_period, (AbstractTestMixin, unittest.TestCase), { '__module__': __name__, 'modname': orig_modname }) globals()[cls.__name__] = cls
def _create_tests(cls): path = modname = orig_modname = None for path, modname in modules.walk_modules(include_so=False, recursive=True, check_optional=False): orig_modname = modname test_name = 'test_%s' % orig_modname.replace('.', '_') modname = modname.replace('gevent.', '').split('.')[0] fn = lambda self, n=orig_modname: self._test(n) if not modname: # pragma: no cover # With walk_modules, can we even get here? fn = unittest.skip( "No such module '%s' at '%s'" % (orig_modname, path))(fn) setattr(cls, test_name, fn) return cls
def _create_tests(cls): path = modname = orig_modname = None for path, modname in modules.walk_modules(include_so=False, recursive=True, check_optional=False): orig_modname = modname test_name = 'test_%s' % orig_modname.replace('.', '_') modname = modname.replace('gevent.', '').split('.')[0] fn = lambda self, n=orig_modname: self._test(n) if not modname: # pragma: no cover # With walk_modules, can we even get here? fn = unittest.skip("No such module '%s' at '%s'" % (orig_modname, path))(fn) setattr(cls, test_name, fn) return cls
def make_all_tests(): for path, module in walk_modules(recursive=True): if module.endswith(NON_APPLICABLE_SUFFIXES): continue make_exec_test(path, module)
class Test(unittest.TestCase): stdlib_has_all = False stdlib_all = () stdlib_name = None stdlib_module = None module = None __implements__ = __extensions__ = __imports__ = () def check_all(self): "Check that __all__ is present and does not contain invalid entries" if not hasattr(self.module, '__all__'): self.assertIn(self.modname, NO_ALL) return names = {} six.exec_("from %s import *" % self.modname, names) names.pop('__builtins__', None) self.assertEqual(sorted(names), sorted(self.module.__all__)) def check_all_formula(self): "Check __all__ = __implements__ + __extensions__ + __imported__" all_calculated = self.__implements__ + self.__imports__ + self.__extensions__ self.assertEqual(sorted(all_calculated), sorted(self.module.__all__)) def check_implements_presence_justified(self): "Check that __implements__ is present only if the module is modeled after a module from stdlib (like gevent.socket)." if self.modname in ALLOW_IMPLEMENTS: return if self.__implements__ is not None and self.stdlib_module is None: raise AssertionError( '%r has __implements__ but no stdlib counterpart (%s)' % (self.modname, self.stdlib_name)) def set_stdlib_all(self): self.assertIsNotNone(self.stdlib_module) self.stdlib_has_all = True self.stdlib_all = getattr(self.stdlib_module, '__all__', None) if self.stdlib_all is None: self.stdlib_has_all = False self.stdlib_all = dir(self.stdlib_module) self.stdlib_all = [ name for name in self.stdlib_all if not name.startswith('_') ] self.stdlib_all = [ name for name in self.stdlib_all if not isinstance( getattr(self.stdlib_module, name), types.ModuleType) ] def check_implements_subset_of_stdlib_all(self): "Check that __implements__ + __imports__ is a subset of the corresponding standard module __all__ or dir()" for name in self.__implements__ + self.__imports__: if name in self.stdlib_all: continue if name in COULD_BE_MISSING.get(self.stdlib_name, ()): continue if name in dir( self.stdlib_module ): # like thread._local which is not in thread.__all__ continue raise AssertionError( '%r is not found in %r.__all__ nor in dir(%r)' % (name, self.stdlib_module, self.stdlib_module)) def check_implements_actually_implements(self): """Check that the module actually implements the entries from __implements__""" for name in self.__implements__: item = getattr(self.module, name) try: stdlib_item = getattr(self.stdlib_module, name) self.assertIsNot(item, stdlib_item) except AttributeError: if name not in COULD_BE_MISSING.get(self.stdlib_name, []): raise def check_imports_actually_imports(self): """Check that the module actually imports the entries from __imports__""" for name in self.__imports__: item = getattr(self.module, name) stdlib_item = getattr(self.stdlib_module, name) self.assertIs(item, stdlib_item) def check_extensions_actually_extend(self): """Check that the module actually defines new entries in __extensions__""" if self.modname in EXTRA_EXTENSIONS: return for name in self.__extensions__: if hasattr(self.stdlib_module, name): raise AssertionError( "'%r' is not an extension, it is found in %r" % (name, self.stdlib_module)) def check_completeness(self): # pylint:disable=too-many-branches """Check that __all__ (or dir()) of the corresponsing stdlib is a subset of __all__ of this module""" missed = [] for name in self.stdlib_all: if name not in getattr(self.module, '__all__', []): missed.append(name) # handle stuff like ssl.socket and ssl.socket_error which have no reason to be in gevent.ssl.__all__ if not self.stdlib_has_all: for name in missed[:]: if hasattr(self.module, name): missed.remove(name) # remove known misses not_implemented = NOT_IMPLEMENTED.get(self.stdlib_name) if not_implemented is not None: result = [] for name in missed: if name in not_implemented: # We often don't want __all__ to be set because we wind up # documenting things that we just copy in from the stdlib. # But if we implement it, don't print a warning if getattr(self.module, name, self) is self: print('IncompleteImplWarning: %s.%s' % (self.modname, name)) else: result.append(name) missed = result if missed: if self.stdlib_has_all: msg = '''The following items in %r.__all__ are missing from %r: %r''' % (self.stdlib_module, self.module, missed) else: msg = '''The following items in dir(%r) are missing from %r: %r''' % (self.stdlib_module, self.module, missed) raise AssertionError(msg) def _test(self, modname): if modname.endswith(PLATFORM_SPECIFIC_SUFFIXES): return self.modname = modname with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) self.module = importlib.import_module(modname) self.check_all() self.__implements__ = getattr(self.module, '__implements__', None) self.__imports__ = getattr(self.module, '__imports__', []) self.__extensions__ = getattr(self.module, '__extensions__', []) self.stdlib_name = MAPPING.get(modname) self.stdlib_module = None if self.stdlib_name is not None: try: self.stdlib_module = __import__(self.stdlib_name) except ImportError: pass self.check_implements_presence_justified() if self.stdlib_module is None: return # use __all__ as __implements__ if self.__implements__ is None: self.__implements__ = sorted(self.module.__all__) self.set_stdlib_all() self.check_implements_subset_of_stdlib_all() self.check_implements_actually_implements() self.check_imports_actually_imports() self.check_extensions_actually_extend() self.check_completeness() path = modname = orig_modname = None for path, modname in walk_modules(include_so=False, recursive=True): orig_modname = modname modname = modname.replace('gevent.', '').split('.')[0] if not modname: print("WARNING: No such module '%s' at '%s'" % (orig_modname, path), file=sys.stderr) continue exec('''def test_%s(self): self._test("%s")''' % (orig_modname.replace('.', '_').replace('-', '_'), orig_modname)) del path, modname, orig_modname
def prereleaser_middle(data): # pragma: no cover """ zest.releaser prerelease middle hook for gevent. The prerelease step: asks you for a version number updates the setup.py or version.txt and the CHANGES/HISTORY/CHANGELOG file (with either this new version number and offers to commit those changes to git The middle hook: All data dictionary items are available and some questions (like new version number) have been asked. No filesystem changes have been made yet. It is our job to finish up the filesystem changes needed, including: - Calling towncrier to handle CHANGES.rst - Add the version number to ``versionadded``, ``versionchanged`` and ``deprecated`` directives in Python source. """ if data['name'] != 'gevent': # We are specified in ``setup.cfg``, not ``setup.py``, so we do not # come into play for other projects, only this one. We shouldn't # need this check, but there it is. return import re import os import subprocess from gevent.testing import modules new_version = data['new_version'] # Generate CHANGES.rst, remove old news entries. subprocess.check_call( ['towncrier', 'build', '--version', data['new_version'], '--yes']) data['update_history'] = False # Because towncrier already did. # But unstage it; we want it to show in the diff zest.releaser will do subprocess.check_call([ 'git', 'restore', '--staged', 'CHANGES.rst', ]) # Put the version number in source files. regex = re.compile(b'.. (versionchanged|versionadded|deprecated):: NEXT') if not isinstance(new_version, bytes): new_version_bytes = new_version.encode('ascii') else: new_version_bytes = new_version new_version_bytes = new_version.encode('ascii') replacement = br'.. \1:: %s' % (new_version_bytes, ) for path, _ in modules.walk_modules( # Start here basedir=os.path.join(data['reporoot'], 'src', 'gevent'), # Include sub-dirs recursive=True, # Include tests include_tests=True, # and other things usually excluded excluded_modules=(), # Don't return build binaries include_so=False, # Don't try to import things; we want all files. check_optional=False, ): with open(path, 'rb') as f: contents = f.read() new_contents, count = regex.subn(replacement, contents) if count: print("Replaced version NEXT in", path) with open(path, 'wb') as f: f.write(new_contents)