def test_variable_arglengths():
    pop = quickstart('foo', df=pandas.DataFrame({'a': [11, 22]}),
                     session_capture_name='test_population.py')
    spec = pm.compile_argspec_transforms(hasvarargs, {'population_name': 0})
    assert ['_u'] == spec['required_names']
    assert 2 == len(spec['required_transformers'])
    assert ['pop'] == spec['optional_names']
    assert 1 == len(spec['optional_transformers'])
    xfm = spec['optional_transformers']['pop']
    assert None == xfm(pop, {})
    assert 7 == xfm(pop, {'pop': 7})
    assert None == xfm(pop, {'zip': 7})
    assert 'args' == spec['varargs']
    assert None == spec['varkw']
    
    assert ('foo', 1, 3) == pop.hasvarargs("U", 1, 2, 3, 4)
    assert ('foo', 'pip', 3) == pop.hasvarkw("U", pop='pip', a=1, b=2, c=3)
    assert ('foo', None, 0, 0) == pop.hasboth_arg('U', 'V')
    assert ('foo', 'W', 1, 2) == pop.hasboth_arg("U", "V", "W", "X",
                                                 y="Y", z="Z")
    assert ('foo', 'foo', 0, 0) == pop.hasboth_argkwarg('U', 'V')
    assert ('foo', 'W', 1, 2) == pop.hasboth_argkwarg("U", "V", "W", "X",
                                                      y="Y", z="Z")
    assert ('foo', 'fizz', 0, 0) == pop.hasboth_haspop('U', 'V')
    
    with pytest.raises(TypeError) as exc:
        pop.hasvarargs("U", 1, 2, 3, 4, pop='pip')
    assert "multiple values for keyword argument 'pop'" in str(exc.value)
    with pytest.raises(TypeError):
        pop.hasvarargs("U", 1, 2, a=1, b=2)
    with pytest.raises(TypeError):
        pop.hasvarkw("U", 1, 2, 3, 4, 5, 6, 7)
    with pytest.raises(TypeError):
        pop.hasboth_arg()
    with pytest.raises(TypeError):
        pop.hasboth_argkwarg()
        
    # Can only fill named parameters with population-implicit values.
    with pytest.raises(IndexError):
        @pm.population_method(population_name='0')
        def cannot_fill_unnamed_kwargs(*args, **kwargs):
            pass
    with pytest.raises(IndexError):
        @pm.population_method(population_name='pop')
        def cannot_fill_unnamed_args(*args, **kwargs):
            pass
示例#2
0
def prepare():
    if testvars['dataset'] is None:
        (df, csv_data) = test_plot_utils.dataset(40)
        tempd = tempfile.mkdtemp(prefix="bdbcontrib-test-population")
        csv_path = os.path.join(tempd, "data.csv")
        with open(csv_path, "w") as csv_f:
            csv_f.write(csv_data.getvalue())
        bdb_path = os.path.join(tempd, "data.bdb")
        name = ''.join(random.choice(ascii_lowercase) for _ in range(32))
        dts = quickstart(name=name, csv_path=csv_path, bdb_path=bdb_path,
                         logger=CaptureLogger(
                             verbose=pytest.config.option.verbose),
                         session_capture_name="test_population.py")
        ensure_timeout(10, lambda: dts.analyze(models=10, iterations=20))
        testvars['dataset'] = dts
        testvars['input_df'] = df

    yield testvars['dataset'], testvars['input_df']
def test_method_calls():
    pop = quickstart('foo', df=pandas.DataFrame({'a': [11, 22]}),
                     session_capture_name='test_population.py')
    assert 42 == pop.minimal_population_method()
    # It's ok to name or not name your positional args.
    # (But it's a syntax error to have a positional arg after a named one.)
    assert '12foo_cc', pop.example_population_method(
        df1='select * limit 1', df2=pandas.DataFrame({'b': [23, 34]}))
    assert '12foo_cc', pop.example_population_method(
        'select * limit 1', df2=pandas.DataFrame({'b': [23, 34]}))
    assert '12foo_cc', pop.example_population_method(
        'select * limit 1', pandas.DataFrame({'b': [23, 34]}))
    # It's okay to name them and get them in the wrong order too.
    assert '12foo_cc', pop.example_population_method(
        df2=pandas.DataFrame({'b': [23, 34]}), df1='select * limit 1')

    # The bdb argument should be present and explained in the function, and
    # should be absent in the method, where it's implicit.
    as_method = pop.example_population_method.__doc__
    as_function = example_population_method.__doc__
    assert not re.search(r'bdb', as_method), as_method
    assert re.search('bdb', as_function), as_function

    with pytest.raises(TypeError) as exc:
        pop.minimal_population_method(3)
    assert ('test_population_method.minimal_population_method()'
            ' takes no arguments (1 given)' == str(exc.value)), repr(exc)

    epm="test_population_method.example_population_method()"
    with pytest.raises(TypeError) as exc:
        pop.example_population_method([5])
    assert (epm + " takes at least 2 arguments (1 given)"
            == str(exc.value)), repr(exc)

    with pytest.raises(TypeError) as exc:
        pop.example_population_method([5], gen=True)
    # This message is among Python's uglier warts, but I want to be consistent.
    assert (epm + " takes at least 2 arguments (2 given)"
            == str(exc.value)), repr(exc)

    with pytest.raises(TypeError) as exc:
        pop.example_population_method([1], [2], [3], [4])
    assert (epm + " takes at most 3 arguments (4 given)"
            == str(exc.value)), repr(exc)

    with pytest.raises(TypeError) as exc:
        pop.example_population_method("SELECT * FROM %t", "SELECT * FROM %g",
                                      b="bang")
    assert (epm + " got an unexpected keyword argument 'b'"
            == str(exc.value)), repr(exc)

    with pytest.raises(TypeError) as exc:
        pop.example_population_method(
            "SELECT * FROM %t", df1="SELECT * FROM %g")
    # This is another misleading message, because the only way for it to happen
    # is with a required positional argument that happens to be named at the
    # call site. A caller might, in this case, expect keywords to be interpreted
    # first, for example, and positional arguments consumed in order thereafter.
    # Not to say that that would be a better choice. I would simply prefer "for
    # 2nd argument df1" rather than "for keyword argument df1".
    # Again, I find it more important to be consistent than to be right.
    assert (epm + " got multiple values for keyword argument 'df1'"
            == str(exc.value)), repr(exc)