def test__get_modules(tmpd): # make a temporary directory with some files and subdirs dirs = [("a",), ("b",), ("c",), ("a", "1"), ("a", "2"), ("a", "2", "i")] for d in dirs: os.mkdir(os.path.join(tmpd, *d)) files_skip = [ ("__init__.py",), ("foo.sh",), ("a", "bar.py"), ("a", "1", "__init__.py"), ("a", "2", "i", "__init__.py"), ("c", "__init__.py"), ("c", "data.dat"), ] for f in files_skip: path = os.path.join(tmpd, *f) open(path, "w").write("SKIP\n") files_find = [ ("foo.py",), ("a", "bar.py"), ("a", "1", "file.py"), ("a", "2", "i", "file.py"), ("b", "foo.py"), ] wlk = codesearch.ModuleClassWalker(from_path=tmpd) expect_modules = set() for f in files_find: path = os.path.join(tmpd, *f) open(path, "w").write("FIND\n") modname = ".".join([wlk._pkg] + list(f))[:-3] # strip '.py' expect_modules.add(modname) for mod in wlk._get_modules(): assert mod in expect_modules expect_modules.remove(mod) assert not expect_modules
def test_warnings(): walker = codesearch.ModuleClassWalker(from_pkg=idaes, class_expr='_TestClass', parent_class=codesearch._TestClass, suppress_warnings=False, exclude_dirs=['contrib']) _visit(walker)
def index_property_metadata(dmf, pkg=idaes, expr="_PropertyMetadata.*", default_version="0.0.1", **kwargs): """Index all the PropertyMetadata classes in this package. Usually the defaults will be correct, but you can modify the package explored and set of classes indexed. When you re-index the same class (in the same module), whether or not that is a "duplicate" will depend on the version found in the containing module. If there is no version in the containing module, the default version is used (so it is always the same). If it is a duplicate, nothing is done, this is not considered an error. If a new version is added, it will be explicitly connected to the highest version of the same module/code. So, for example, 1. Starting with (a.module.ClassName version=0.1.2) 2. If you then find a new version (a.module.ClassName version=1.2.3) There will be 2 resources, and you will have the relation:: a.module.ClassName/1.2.3 --version---> a.module.ClassName/0.1.2 3. If you add another version (a.module.ClassName version=1.2.4), you will have two relations:: a.module.ClassName/1.2.3 --version---> a.module.ClassName/0.1.2 a.module.ClassName/1.2.4 --version---> a.module.ClassName/1.2.3 Args: dmf (idaes.dmf.DMF): Data Management Framework instance in which to record the found metadata. pkg (module): Root module (i.e. package root) from which to find the classes containing metadata. expr (str): Regular expression pattern for the names of the classes in which to look for metadata. default_version (str): Default version to use for modules with no explicit version. kwargs: Other keyword arguments passed to :class:`codesearch.ModuleClassWalker`. Returns: codesearch.ModuleClassWalker: Class that walked through the modules. You can call `.get_indexed_classes()` to see the list of classes walked, or `.walk()` to walk the modules again. Raises: This instantiated a `DMFVisitor` and calls its `walk()` method to walk/visit each found class, so any exception raised by the constructor or `DMFVisitor.visit_metadata()`. """ wlk = codesearch.ModuleClassWalker( from_pkg=pkg, class_expr=expr, parent_class=idaes.core.property_meta.HasPropertyClassMetadata, suppress_warnings=True, **kwargs) vst = DMFVisitor(dmf, default_version=default_version) wlk.walk(vst) return wlk
def test_from_pkg_no_path(): import os try: codesearch.ModuleClassWalker(from_pkg=os, **walker_args) except IOError: pass else: assert False
def test_bad_path(): try: codesearch.ModuleClassWalker( from_path="/a/b/c", from_pkg=idaes, class_expr="_TestClass" ) except IOError: pass else: assert False
def test_get_metadata_unimplemented(dummy_package): print("@@ GMU sys.path={}".format(sys.path)) f = open(os.path.join(dummy_package, "unimpl.py"), "w") f.write("class U(object):\n" " @classmethod\n" " def get_metadata(cls):\n" " raise NotImplementedError\n") f.close() w = codesearch.ModuleClassWalker(from_path=dummy_package, suppress_warnings=True) visitor = codesearch.PropertyMetadataVisitor() w.walk(visitor)
def test__get_modules(tmpd): # make a temporary directory with some files and subdirs dirs = [('a', ), ('b', ), ('c', ), ('a', '1'), ('a', '2'), ('a', '2', 'i')] for d in dirs: os.mkdir(os.path.join(tmpd, *d)) files_skip = [('__init__.py', ), ('foo.sh', ), ('a', 'bar.py'), ('a', '1', '__init__.py'), ('a', '2', 'i', '__init__.py'), ('c', '__init__.py'), ('c', 'data.dat')] for f in files_skip: path = os.path.join(tmpd, *f) open(path, 'w').write('SKIP\n') files_find = [('foo.py', ), ('a', 'bar.py'), ('a', '1', 'file.py'), ('a', '2', 'i', 'file.py'), ('b', 'foo.py')] wlk = codesearch.ModuleClassWalker(from_path=tmpd) expect_modules = set() for f in files_find: path = os.path.join(tmpd, *f) open(path, 'w').write('FIND\n') modname = '.'.join([wlk._pkg] + list(f))[:-3] # strip '.py' expect_modules.add(modname) for mod in wlk._get_modules(): assert mod in expect_modules expect_modules.remove(mod) assert not expect_modules
def package_walker(): """This walker is also a test. But useful as a base for other things. """ walker = codesearch.ModuleClassWalker(from_pkg=idaes, **walker_args) yield walker
def test_noexclude(dummy_package): walker_args_noexclude.update(dict(from_path=dummy_package)) w = codesearch.ModuleClassWalker(**walker_args_noexclude) w.walk(DummyVisitor())
def test_cannot_import_nowarn(dummy_package): w = codesearch.ModuleClassWalker(from_path=dummy_package, suppress_warnings=True) w.walk(DummyVisitor()) assert len(w.get_indexed_classes()) == 1
def test_from_path_and_from_pkg(): idpath = idaes.__path__[0] walker = codesearch.ModuleClassWalker( from_path=idpath, from_pkg=idaes, **walker_args ) _visit(walker)
def test_from_pkg_noexpr(): walker = codesearch.ModuleClassWalker(from_pkg=idaes, **walker_args_noex) _visit(walker)