diff --git a/source/src/python/PyRosetta/rosetta.config b/source/src/python/PyRosetta/rosetta.config index ebd29ff392d..9abc12edcdc 100644 --- a/source/src/python/PyRosetta/rosetta.config +++ b/source/src/python/PyRosetta/rosetta.config @@ -659,9 +659,31 @@ -function basic::Tracer::create_impl -function basic::MemTracer::create_impl +###### # Bad/Ambiguous Overloads of copy-constructor, see test T121_core.ResidueSelector.test_residue_selector_ctors for a test case +###### +# RESIDUE SELECTORS +-function core::select::jump_selector::NotJumpSelector::NotJumpSelector(const class core::select::jump_selector::NotJumpSelector &) +-function core::select::jump_selector::AndJumpSelector::AndJumpSelector(const class core::select::jump_selector::AndJumpSelector &) +-function core::select::jump_selector::AndJumpSelector::AndJumpSelector(class std::shared_ptr< const core::select::jump_selector::JumpSelector > ) -function core::select::residue_selector::NotResidueSelector::NotResidueSelector(const class core::select::residue_selector::NotResidueSelector &) - +-function core::select::residue_selector::AndResidueSelector::AndResidueSelector(const class core::select::residue_selector::AndResidueSelector &) +-function core::select::residue_selector::AndResidueSelector::AndResidueSelector(class std::shared_ptr< const core::select::residue_selector::ResidueSelector > ) +-function core::select::residue_selector::RandomGlycanFoliageSelector::RandomGlycanFoliageSelector(const class core::select::residue_selector::RandomGlycanFoliageSelector &) +-function core::select::residue_selector::SymmetricalResidueSelector::SymmetricalResidueSelector(const class core::select::residue_selector::SymmetricalResidueSelector &) +-function core::select::residue_selector::SymmetricalResidueSelector::SymmetricalResidueSelector(class std::shared_ptr< const core::select::residue_selector::ResidueSelector >) +-function core::select::residue_selector::NativeSelector::NativeSelector(const class core::select::residue_selector::NativeSelector &) +-function core::select::residue_selector::SymmetricalResidueSelector::SymmetricalResidueSelector(const class core::select::residue_selector::SymmetricalResidueSelector &) +-function core::select::residue_selector::SymmetricalResidueSelector::SymmetricalResidueSelector(class std::shared_ptr< const core::select::residue_selector::ResidueSelector >) +-function core::pack::task::residue_selector::ClashBasedShellSelector::ClashBasedShellSelector(const class core::pack::task::residue_selector::ClashBasedShellSelector &) +-function core::pack::task::residue_selector::ClashBasedShellSelector::ClashBasedShellSelector(class std::shared_ptr< const core::select::residue_selector::ResidueSelector >) +# PACK DAEMON EXPRESSIONS +-function protocols::pack_daemon::ExpExpression::ExpExpression(const class protocols::pack_daemon::ExpExpression &) +-function protocols::pack_daemon::InSetExpression::InSetExpression(const class protocols::pack_daemon::InSetExpression &) +-function protocols::pack_daemon::LnExpression::LnExpression(const class protocols::pack_daemon::LnExpression &) +# NICHE CLASSES THAT JACK FEELS COMFORTABLE MASKING OUT +-class protocols::mean_field::jagged_array< protocols::mean_field::AAProb > +-class protocols::mean_field::jagged_array< protocols::mean_field::RotProb > # problem with bool specialization? error: address of overloaded function 'swap' does not match required type 'void (core::id::DOF_ID_Map &, core::id::DOF_ID_Map &)' -function core::id::swap diff --git a/source/src/python/PyRosetta/src/test/T003_ParentalShadowing.py b/source/src/python/PyRosetta/src/test/T003_ParentalShadowing.py new file mode 100644 index 00000000000..80109f74e7b --- /dev/null +++ b/source/src/python/PyRosetta/src/test/T003_ParentalShadowing.py @@ -0,0 +1,194 @@ +# :noTabs=true: +# (c) Copyright Rosetta Commons Member Institutions. +# (c) This file is part of the Rosetta software suite and is made available under license. +# (c) The Rosetta software is developed by the contributing members of the Rosetta Commons. +# (c) For more information, see http://www.rosettacommons.org. Questions about this can be +# (c) addressed to University of Washington CoMotion, email: license@uw.edu. + +## @author Jack Maguire + +import pyrosetta +from pyrosetta.rosetta import core, numeric, protocols, basic +import re + +def verbose(): + return False + +class IsBad(): + def __init__(self): + self.bad = False + self.count = 0 + def register(self): + self.bad = True + self.count += 1 + +global_is_bad = IsBad() + +class MyClass: + def __init__(self): + pass + +class GreenListManager: + def __init__(self): + # Only add things here that are overloaded in a way that results in specification, not divergent behavior + self.greenlist_regex = [ + "$", + "$", + " None + l = l.split("->")[0] + # 1. (pose: pyrosetta.rosetta.core.pose.Pose, residue_positions: pyrosetta.rosetta.utility.vector1_bool) + s1 = l.find("(")+1 + s2 = l.rfind(")") + if s1==s2: return [] + l = l[s1:s2] + #pose: pyrosetta.rosetta.core.pose.Pose, residue_positions: pyrosetta.rosetta.utility.vector1_bool + ls = [a.strip().rstrip() for a in l.split( "," )] + #['pose: pyrosetta.rosetta.core.pose.Pose', 'residue_positions: pyrosetta.rosetta.utility.vector1_bool'] + ls = [ a[a.find(":")+1:].strip() for a in ls ] + #['pyrosetta.rosetta.core.pose.Pose', 'pyrosetta.rosetta.utility.vector1_bool'] + ls = [ eval(a) for a in ls ] + #[, ] + # returns a list of classes + return ls + +def signatures_conflict( sig1, sig2, only_enforce_distinct_parents=True ): + # if only_enforce_distinct_parents=True, we will not complain if foo() shadows foo(), we will only complain if foo() shadows foo() where A is a parent of B + if len(sig1) != len(sig2): return False + + if (sig1 == sig2) and only_enforce_distinct_parents: return False + + for i in range(len(sig1)): + class1 = sig1[i] + class2 = sig2[i] + check12 = issubclass( class1, class2 ) and class1 is not bool + check21 = issubclass( class2, class1 ) and class2 is not bool + if not (check12 or check21): + # if neither class clashes with the other one, these two signatures are safe + return False + + return True + + +def test_function( F, custom_name = None ): + + if custom_name is None: + custom_name = str(F) + + if greenlist.bypass( custom_name ): + return + + failed = True + try: + F( MyClass() ) + failed = False + except Exception as E: + exception_str = str(E) + + assert failed, F + assert "The following argument types are supported" in exception_str or "No module named 'numpy'" in exception_str, exception_str + + signatures = [] + for l in exception_str.split("\n"): + if l[0:4] != " " or l[5] != ".": continue + #if "->" not in l: continue + + if "*" in l: + if verbose(): print( "Skipping weird signature", l ) + # like 2. pyrosetta.rosetta.core.chemical.MutableChiRecord(atm_vec: pyrosetta.rosetta.utility.vector1_void_*) + continue + + if "::" in l: + if verbose(): print( "Skipping incompletely bound signature", l ) + continue + + if "Tuple[" in l or "Callable[" in l or "tuple[" in l: + if verbose(): print( "Skipping complicated signature (for now?)", l ) + continue + + try: + sig = extract_class_signature_from_overload_line( l ) + except Exception as e: + if str(e).startswith("name '") and str(e).endswith("' is not defined"): + if verbose(): print( "Skipping incompletely bound signature", l, ":", str(e) ) + continue + print( "ERROR" ) + print( l ) + print( "-----" ) + print( e ) + exit( 0 ) + signatures.append( sig ) + + for i in range(len(signatures)): + for j in range(i+1,len(signatures)): + if signatures_conflict( signatures[i], signatures[j] ): + print( f"CONFLICT `{custom_name}` --- `{signatures[i]}` --- `{signatures[j]}`" ) + global_is_bad.register() + +def test_class( C ): + # 1. test __init__ + try: + test_function( C ) + except AssertionError as E: + if "No constructor defined" in str(E): + if verbose(): print( "No constructor defined for", C ) + pass + else: + raise E + + # 2. test functions + for cname in dir(C): + if cname.startswith("__"): continue + #if cname == "__init__": continue + + cattr = getattr(C,cname) + type_str = str( type( cattr ) ) + if type_str == "": + try: + test_function( cattr, custom_name=f"{C}::{cname}" ) + except AssertionError as e: + if "takes no arguments" in str(e): + pass + else: + raise e + elif type_str == "": + print( cattr ) + exit( 0 ) #testing to see if this is possible + test_module( cattr ) + else: + if verbose(): print( "skipping type", type_str, "for", cname, "in", C ) + +def test_module( D ): + for dname in dir(D): + dattr = getattr(D,dname) + type_str = str( type( dattr ) ) + if type_str == "": + if dname.endswith( "Creator" ): + if verbose(): print( "skipping creator type", dname ) + else: + test_class( dattr ) + elif type_str == "": + test_function( dattr ) + elif type_str == "": + test_module( dattr ) + else: + if verbose(): print( "skipping type", type_str, "for", dname ) + +for module in [core, numeric, protocols, basic]: + test_module( module ) +if global_is_bad.bad: + raise Exception(f"Found {global_is_bad.count} shadowing instances")