def testNodeCmd( funcName, cmdInfo, nodeCmd=False, verbose=False ):

    _logger.info(funcName.center( 50, '='))

    if funcName in [ 'character', 'lattice', 'boneLattice', 'sculpt', 'wire' ]:
        _logger.debug("skipping")
        return cmdInfo
    
    # These cause crashes... confirmed that pointOnPolyConstraint still
    # crashes in 2012
    dangerousCmds = ['doBlur', 'pointOnPolyConstraint']
    if funcName in dangerousCmds:
        _logger.debug("skipping 'dangerous command'")
        return cmdInfo

    def _formatCmd( cmd, args, kwargs ):
        args = [ x.__repr__() for x in args ]
        kwargs = [ '%s=%s' % (key, val.__repr__()) for key, val in kwargs.items() ]
        return '%s( %s )' % ( cmd, ', '.join( args+kwargs ) )

    def _objectToType( result ):
        "convert a an instance or list of instances to a python type or list of types"
        if isinstance(result, list):
            return [ type(x) for x in result ]
        else:
            return type(result)

    _castList = [float, int, bool]

#    def _listIsCastable(resultType):
#        "ensure that all elements are the same type and that the types are castable"
#        try:
#            typ = resultType[0]
#            return typ in _castList and all([ x == typ for x in resultType ])
#        except IndexError:
#            return False

    module = cmds

    try:
        func = getattr(module, funcName)
    except AttributeError:
        _logger.warning("could not find function %s in modules %s" % (funcName, module.__name__))
        return cmdInfo

    # get the current list of objects in the scene so we can cleanup later, after we make nodes
    allObjsBegin = set( cmds.ls(l=1) )
    try:

        # Attempt to create the node
        cmds.select(cl=1)

        # the arglist passed from creation to general testing
        args = []
        constrObj = None
        if nodeCmd:

            #------------------
            # CREATION
            #------------------
            obj = nodeCreationCmd(func, funcName)

            if isinstance(obj, list):
                _logger.debug("Return %s", obj)
                if len(obj) == 1:
                    _logger.info("%s: creation return values need unpacking" % funcName)
                    cmdInfo['resultNeedsUnpacking'] = True
                elif not obj:
                    raise ValueError, "returned object is an empty list"
                objTransform = obj[0]
                obj = obj[-1]

            if obj is None:
                #emptyFunctions.append( funcName )
                raise ValueError, "Returned object is None"

            elif not cmds.objExists( obj ):
                raise ValueError, "Returned object %s is Invalid" % obj

            args = [obj]

    except (TypeError,RuntimeError, ValueError), msg:
        _logger.debug("failed creation: %s", msg)

    else:
        objType = cmds.objectType(obj)
        #------------------
        # TESTING
        #------------------

        #(func, args, data) = cmdList[funcName]
        #(usePyNode, baseClsName, nodeName)
        flags = cmdInfo['flags']

        hasQueryFlag = flags.has_key( 'query' )
        hasEditFlag = flags.has_key( 'edit' )

        anyNumRe = re.compile('\d+')

        for flag in sorted(flags.keys()):
            flagInfo = flags[flag]
            if flag in ['query', 'edit']:
                continue

            assert flag != 'ype', "%s has bad flag" % funcName

            # special case for constraints
            if constrObj and flag in ['weight']:
                flagargs = [constrObj] + args
            else:
                flagargs = args

            try:
                modes = flagInfo['modes']
                testModes = False
            except KeyError, msg:
                #raise KeyError, '%s: %s' % (flag, msg)
                #_logger.debug(flag, "Testing modes")
                flagInfo['modes'] = []
                modes = []
                testModes = True

            # QUERY
            val = None
            argtype = flagInfo['args']

            if 'query' in modes or testModes == True:
                if hasQueryFlag:
                    kwargs = {'query':True, flag:True}
                else:
                    kwargs = { flag:True }

                cmd = _formatCmd(funcName, flagargs, kwargs)
                try:
                    _logger.debug(cmd)
                    val = func( *flagargs, **kwargs )
                    #_logger.debug(val)
                    resultType = _objectToType(val)

                    # ensure symmetry between edit and query commands:
                    # if this flag is queryable and editable, then its queried value should be symmetric to its edit arguments
                    if 'edit' in modes and argtype != resultType:
                        # there are certain patterns of asymmetry which we can safely correct:
                        singleItemList = (isinstance( resultType, list)
                                          and len(resultType) ==1
                                          and 'multiuse' not in flagInfo.get('modes', []))
                        
                        # [bool] --> bool
                        if singleItemList and resultType[0] == argtype:
                            _logger.info("%s, %s: query flag return values need unpacking" % (funcName, flag))
                            flagInfo['resultNeedsUnpacking'] = True
                            val = val[0]

                        # [int] --> bool
                        elif singleItemList and argtype in _castList and resultType[0] in _castList:
                            _logger.info("%s, %s: query flag return values need unpacking and casting" % (funcName, flag))
                            flagInfo['resultNeedsUnpacking'] = True
                            flagInfo['resultNeedsCasting'] = True
                            val = argtype(val[0])

                        # int --> bool
                        elif argtype in _castList and resultType in _castList:
                            _logger.info("%s, %s: query flag return values need casting" % (funcName, flag))
                            flagInfo['resultNeedsCasting'] = True
                            val = argtype(val)
                        else:
                            # no valid corrctions found
                            _logger.info(cmd)
                            _logger.info("\treturn mismatch")
                            _logger.info('\tresult: %s', val.__repr__())
                            _logger.info('\tpredicted type: %s', argtype)
                            _logger.info('\tactual type:    %s', resultType)
                            # value is no good. reset to None, so that a default will be generated for edit
                            val = None

                    else:
                        _logger.debug("\tsucceeded")
                        _logger.debug('\tresult: %s', val.__repr__())
                        _logger.debug('\tresult type:    %s', resultType)

                except __HOLE__, msg:
                    # flag is no longer supported
                    if str(msg).startswith( 'Invalid flag' ):
                        #if verbose:
                        _logger.info("removing flag %s %s %s", funcName, flag, msg)
                        shortname = flagInfo['shortname']
                        flagInfo.pop(flag,None)
                        flagInfo.pop(shortname,None)
                        modes = [] # stop edit from running
                    else:
                        _logger.info(cmd)
                        _logger.info("\t" + str(msg).rstrip('\n'))
                    val = None

                except RuntimeError, msg:
                    _logger.info(cmd)
                    _logger.info("\t" + str(msg).rstrip('\n') )
                    val = None
                else:
                    # some flags are only in mel help and not in maya docs, so we don't know their
                    # supported per-flag modes.  we fill that in here
                    if 'query' not in flagInfo['modes']:
                        flagInfo['modes'].append('query')
            # EDIT
            if 'edit' in modes or testModes == True:

                #_logger.debug("Args:", argtype)
                try:
                    # we use the value returned from query above as defaults for putting back in as edit args
                    # but if the return was empty we need to produce something to test on.
                    # NOTE: this is just a guess
                    if val is None:

                        if isinstance(argtype, list):
                            val = []
                            for typ in argtype:
                                if type == unicode or isinstance(type,basestring):
                                    val.append('persp')
                                else:
                                    if 'query' in modes:
                                        val.append( typ(0) )
                                    # edit only, ensure that bool args are True
                                    else:
                                        val.append( typ(1) )
                        else:
                            if argtype == unicode or isinstance(argtype,basestring):
                                val = 'persp'
                            elif 'query' in modes:
                                val = argtype(0)
                            else:
                                # edit only, ensure that bool args are True
                                val = argtype(1)

                    kwargs = {'edit':True, flag:val}
                    cmd = _formatCmd(funcName, args, kwargs)
                    _logger.debug(cmd)

                    # some commands will either delete or rename a node, ie:
                    #     spaceLocator(e=1, name=...)
                    #     container(e=1, removeContainer=True )
                    # ...which will then make subsequent cmds fail.
                    # To get around this, we need to undo the cmd.
                    try:
                        cmds.undoInfo(openChunk=True)
                        editResult = func( *args, **kwargs )
                    finally:
                        cmds.undoInfo(closeChunk=True)

                    if not cmds.objExists(obj):
                        # cmds.camera(e=1, name=...) does weird stuff - it
                        # actually renames the parent transform, even if you give
                        # the name of the shape... which means the shape
                        # then gets a second 'Shape1' tacked at the end...
                        # ...and in addition, undo is broken as well.
                        # So we need a special case for this, where we rename...
                        if objType == 'camera' and flag == 'name':
                            _logger.info('\t(Undoing camera rename)')
                            renamePattern = anyNumRe.sub('*', obj)
                            possibleRenames = cmds.ls(renamePattern, type=objType)
                            possibleRenames = [x for x in possibleRenames
                                               if x not in allObjsBegin]
                            # newName might not be the exact same as our original,
                            # but as long as it's the same maya type, and isn't
                            # one of the originals, it shouldn't matter...
                            newName = possibleRenames[-1]
                            cmds.rename(newName, obj)
                        else:
                            _logger.info('\t(Undoing cmd)')
                            cmds.undo()
                    _logger.debug("\tsucceeded")
                    #_logger.debug('\t%s', editResult.__repr__())
                    #_logger.debug('\t%s %s', argtype, type(editResult))
                    #_logger.debug("SKIPPING %s: need arg of type %s" % (flag, flagInfo['argtype']))
                except TypeError, msg:
                    if str(msg).startswith( 'Invalid flag' ):
                        #if verbose:
                        # flag is no longer supported
                        _logger.info("removing flag %s %s %s", funcName, flag, msg)
                        shortname = flagInfo['shortname']
                        flagInfo.pop(flag,None)
                        flagInfo.pop(shortname,None)
                    else:
                        _logger.info(funcName)
                        _logger.info("\t" + str(msg).rstrip('\n'))
                        _logger.info("\tpredicted arg: %s", argtype)
                        if not 'query' in modes:
                            _logger.info("\tedit only")
                except RuntimeError, msg:
                    _logger.info(cmd)
                    _logger.info("\t" + str(msg).rstrip('\n'))
                    _logger.info("\tpredicted arg: %s", argtype)
                    if not 'query' in modes:
                        _logger.info("\tedit only")
                else:
                    if 'edit' not in flagInfo['modes']:
                        flagInfo['modes'].append('edit')

    # cleanup
    allObjsEnd = set( cmds.ls(l=1) )
    newObjs = list(allObjsEnd.difference(  allObjsBegin ) )
    if newObjs:
        cmds.delete( newObjs )
    return cmdInfo
dataset/ETHPy150Open CountZer0/PipelineConstructionSet/python/maya/site-packages/pymel-1.0.3/pymel/internal/cmdcache.py/testNodeCmd