def argumentos_que_toman_valores_obtienen_defaults_anulados_correctamente( self): # noqa args = (Argumento("arg", tipo=str), Argumento("arg2", tipo=int)) c = Contexto("miartefacto", args=args) argv = ["miartefacto", "--arg", "mival", "--arg2", "25"] resultado = Analizador((c, )).analizar_args(argv) assert resultado[0].args["arg"].valor == "mival" assert resultado[0].args["arg2"].valor == 25
def no_hay_ambiguedad_si_la_opcion_val_ya_se_ha_dado(self): p = self._analizador(( Argumento("foo", opcional=True), Argumento("bar", tipo=bool), )) # Esto NO debería suscitar un análisis de errores. resultado = self._analizar("--foo hola --bar", p) assert resultado[0].args["foo"].valor == "hola" assert resultado[0].args["bar"].valor is True
def argumento_valido_NOT_es_ambiguo(self): # La única excepción que prueba la regla # self._analizador((Argumento("foo", opcional=True), Argumento("bar"))) for form in ("--bar barval", "--bar=barval"): resultado = self._analizar("--foo {}".format(form)) assert len(resultado) == 1 args = resultado[0].args assert args["foo"].valor is True assert args["bar"].valor == "barval"
def representa_valores_perdidos_de_argumentos_posicionales(self): arg1 = Argumento("arg1", posicional=True) arg2 = Argumento("arg2", posicional=False) arg3 = Argumento("arg3", posicional=True) c = Contexto(nombre="foo", args=(arg1, arg2, arg3)) assert c.faltan_argumentos_posicionales == [arg1, arg3] c.args_posicionales[0].valor = "wat" assert c.faltan_argumentos_posicionales == [arg3] c.args_posicionales[1].valor = "hrm" assert c.faltan_argumentos_posicionales == []
def argumentos_devueltos_no_dados_contienen_valores_pordefecto(self): # Es decir un Contexto con argumentos A y B, dued sin mención # de B, debería resultar en B existente en el resultado, con # None, o el argumento no existe. a = Argumento("nombre", tipo=str) b = Argumento("edad", default=7) c = Contexto("miartefacto", args=(a, b)) Analizador( (c, )).analizar_args(["miartefacto", "--nombre", "blah"]) assert c.args["edad"].valor == 7
def argumento_valido_de_bandera_no_es_ambiguo(self): # The OTHER exception that proves the rule? self._analizador(( Argumento("foo", opcional=True), Argumento("bar", tipo=bool), )) resultado = self._analizar("--foo --bar") assert len(resultado) == 1 args = resultado[0].args assert args["foo"].valor is True assert args["bar"].valor is True
def tipo_lista_de_desencadenadores_anexar_en_lugar_de_sobrescribir(self): # TODO: cuando se pone de esta manera hace que la API se vea # bastante extraña; tal vez un signo, deberíamos cambiar a métodos # de establecimiento explícitos (seleccionados en tipo, tal vez) # en lugar de usar un establecedor implícito a = Argumento("milista", tipo=list) assert a.valor == [] a.valor = "val1" assert a.valor == ["val1"] a.valor = "val2" assert a.valor == ["val1", "val2"]
def maneja_multiples_banderas_booleanas_por_contexto(self): c = Contexto( "miartefacto", args=(Argumento("foo", tipo=bool), Argumento("bar", tipo=bool)), ) r = Analizador([c ]).analizar_args(["miartefacto", "--foo", "--bar"]) a = r[0].args assert a.foo.valor is True assert a.bar.valor is True
def incremento_True_desencadena_el_incremento_por_default(self): a = Argumento("verbose", tipo=int, default=0, incremento=True) assert a.valor == 0 # NOTE: el analizador actualmente sólo dice "Argumento.toma_valor # es falso? Va a poner True/False ahí." Así que esto parece bastante # tonto fuera de contexto (como con los tipos-de-lista de arriba.) a.valor = True assert a.valor == 1 for _ in range(4): a.valor = True assert a.valor == 5
def setup(self): # Contexto normal, no relacionado con artefacto/colección self.ordinario = Contexto( args=(Argumento("foo"), Argumento("bar", help="bar el baz"))) # Artefacto/Colección Contexto generado # (expondrá banderas n tales) @artefacto(help={"otroarg": "otra ayuda"}, opcional=["valopc"]) def miartefacto(c, miarg, otroarg, valopc, intval=5): pass col = Coleccion(miartefacto) self.tasked = col.a_contextos()[0]
def arg_posicionales_omitidos_genera_ParseError(self): try: arg = Argumento("pos", posicional=True) arg2 = Argumento("maspos", posicional=True) miartefacto = Contexto(nombre="miartefacto", args=[arg, arg2]) Analizador(contextos=[miartefacto]).analizar_args( ["miartefacto"]) except ErrorDeAnalisis as e: esperado = "'miartefacto' no recibió los argumentos posicionales requeridos: 'pos', 'maspos'" # noqa assert str(e) == esperado else: assert False, "No subió ErrorDeAnalisis!"
def iterables_funcionan_correctamente_fuera_de_un_vacio(self): # Error no detectado donde estaba principalmente enfocado en el # caso de uso -vvv ... ¡los incrementables 'normales' nunca # dejaron el estado 'esperando valor' en el analizador! así que # _subsequent_ artefacto nombres & such nunca se analizaron # correctamente, siempre se agregaron a la lista. c = Contexto("miartefacto", args=[Argumento("milista", tipo=list)]) c2 = Contexto("otroartefacto") argv = [ "miartefacto", "--milista", "val", "--milista", "val2", "otroartefacto", ] resultado = Analizador([c, c2]).analizar_args(argv) # Cuando el error está presente, el resultado solo tiene un # contexto (para 'mi artefacto') y su 'milista' consiste en # ['val', 'val2', 'otro artefacto']. (el medio '--milista' se # manejó semi-correctamente). milista = resultado[0].args.milista.valor assert milista == ["val", "val2"] contextos = len(resultado) err = "¡Obtuve {} resultados de análisis de contexto en lugar de 2!".format( contextos) assert contextos == 2, err assert resultado[1].nombre == "otroartefacto"
def nombre_de_artefacto(self): # miartefacto --foo myotroartefacto c1 = Contexto("miartefacto", args=(Argumento("foo", opcional=True), )) c2 = Contexto("otroartefacto") p = Analizador([c1, c2]) self._prueba_para_ambiguedad("--foo otroartefacto", p)
def args_posicionales_comen_nombres_de_contexto_validos_de_otra_manera( self): miartefacto = Contexto( "miartefacto", args=[ Argumento("pos", posicional=True), Argumento("nonpos", default="default"), ], ) Contexto("lolwut") resultado = Analizador([miartefacto]).analizar_args( ["miartefacto", "lolwut"]) r = resultado[0] assert r.args["pos"].valor == "lolwut" assert r.args["nonpos"].valor == "default" assert len(resultado) == 1 # Not 2
def bool_core_pero_por_cadena_de_artefacto(self): # Contexto inicial de análisis con bool --ocultar, y un # artefacto con un regular (cadena) --ocultar inicial = Contexto( args=[Argumento("ocultar", tipo=bool, default=False)]) artefacto1 = Contexto("miartefacto", args=[Argumento("ocultar")]) analizador = Analizador(inicial=inicial, contextos=[artefacto1]) # Espera que, como la versión del artefacto gana, seamos # capaces de llamarlo con un valor. (Si hubiera bichos raros # en los que la bandera del núcleo informara al análisis, esto fallaría.) resultado = analizador.analizar_args( ["miartefacto", "--ocultar", "ambos"]) assert resultado[0].args.ocultar.valor is False assert resultado[1].args.ocultar.valor == "ambos"
def argumentos_miembros_de_contexto_devueltos_contienen_valores_dados( self): c = Contexto("miartefacto", args=(Argumento("booleano", tipo=bool), )) resultado = Analizador( (c, )).analizar_args(["miartefacto", "--booleano"]) assert resultado[0].args["booleano"].valor is True
def _analizador(self, arguments=None): if arguments is None: arguments = (Argumento(nombres=("foo", "f"), opcional=True, default="midefault"), ) self.contexto = Contexto("miartefacto", args=arguments) self.analizador = Analizador([self.contexto]) return self.analizador
def por_si_mismo_caso_base(self): artefacto1 = Contexto("miartefacto") init = Contexto(args=[Argumento("help", opcional=True)]) analizador = Analizador(inicial=init, contextos=[artefacto1]) resultado = analizador.analizar_args(["miartefacto", "--help"]) assert len(resultado) == 2 assert resultado[0].args.help.valor == "miartefacto" assert "help" not in resultado[1].args
def args_de_artefacto_funcionan_correctamente(self): artefacto1 = Contexto("miartefacto", args=(Argumento("bah"), )) resultado = Analizador((artefacto1, )).analizar_args([ "miartefacto", "--bah", "mehval1", "miartefacto", "--bah", "mehval2" ]) assert resultado[0].args.bah.valor == "mehval1" assert resultado[1].args.bah.valor == "mehval2"
def args_posicionales_todavia_se_pueden_dar_como_banderas(self): # AKA "argumentos posicionales pueden venir en cualquier parte del contexto" pos1 = Argumento("pos1", posicional=True) pos2 = Argumento("pos2", posicional=True) nonpos = Argumento("nonpos", posicional=False, default="jeje") miartefacto = Contexto("miartefacto", args=[pos1, pos2, nonpos]) assert miartefacto.args_posicionales == [pos1, pos2] r = Analizador([miartefacto]).analizar_args([ "miartefacto", "--nonpos", "hum", "--pos2", "pos2val", "pos1val", ])[0] assert r.args["pos1"].valor == "pos1val" assert r.args["pos2"].valor == "pos2val" assert r.args["nonpos"].valor == "hum"
def valor_que_requiere_que_banderas_cores_tambien_trabajen_correctamente( self): "banderas de núcleo que requieren-valor también funcionan correctamente" inicial = Contexto(args=[Argumento("ocultar")]) artefacto1 = Contexto("miartefacto") analizador = Analizador(inicial=inicial, contextos=[artefacto1]) resultado = analizador.analizar_args( ["miartefacto", "--ocultar", "ambos"]) assert resultado[0].args.ocultar.valor == "ambos"
def otros_tokens_luego_generan_errores_de_analisis(self): # NOTE: esto se debe a la carcasa especial donde suministramos # el nombre del artefacto como valor cuando la bandera se # llama literalmente "ayuda". artefacto1 = Contexto("miartefacto") init = Contexto(args=[Argumento("help", opcional=True)]) analizador = Analizador(inicial=init, contextos=[artefacto1]) with raises(ErrorDeAnalisis, match=r".*foobar.*"): analizador.analizar_args( ["miartefacto", "--help", "foobar"])
def clona_contexto_inicial(self): a = Argumento("foo", tipo=bool) assert a.valor is None c = Contexto(args=(a, )) p = Analizador(inicial=c) assert p.inicial is c r = p.analizar_args(["--foo"]) assert p.inicial is c c2 = r[0] assert c2 is not c a2 = c2.args["foo"] assert a2 is not a assert a.valor is None assert a2.valor is True
def clona_sin_contextos_iniciales(self): a = Argumento("foo") assert a.valor is None c = Contexto(nombre="miartefacto", args=(a, )) p = Analizador(contextos=(c, )) assert p.contextos["miartefacto"] is c r = p.analizar_args(["miartefacto", "--foo", "val"]) assert p.contextos["miartefacto"] is c c2 = r[0] assert c2 is not c a2 = c2.args["foo"] assert a2 is not a assert a.valor is None assert a2.valor == "val"
def puede_tomar_una_instancia_de_Argumento(self): a = Argumento(nombres=("foo", )) self.c.agregar_arg(a) assert self.c.args["foo"] is a
def args_se_muestran_como_repr(self): cadena = str(Contexto("bar", args=[Argumento("arg1")])) assert (cadena == "<analizador/Contexto 'bar': {'arg1': <Argumento: arg1>}>" ) # noqa
def setup(self): self.c = Contexto(args=( Argumento("foo"), Argumento(nombres=("bar", "biz")), Argumento("baz", nombre_de_atributo="wat"), ))
def _assert_de_orden(self, name_tuples, expected_bandera_order): c = Contexto(args=[Argumento(nombres=x) for x in name_tuples]) esperado = [c.ayuda_para(x) for x in expected_bandera_order] assert c.help_tuplas() == esperado
def args_por_defecto_verdad(self): c = Contexto( args=(Argumento("esverdad", tipo=bool, default=True), )) assert c.ayuda_para("--esverdad") == ("--[no-]esverdad", "")
def guiionbajo_args(self): c = Contexto( args=(Argumento("yo_tengo_guionesbajos", help="yup"), )) resultado = c.ayuda_para("--yo-tengo-guionesbajos") assert resultado == ("--yo-tengo-guionesbajos=CADENA", "yup")