TST(string dtype): Resolve xfails in test_from_dummies
State: closed

- [ ] closes #xxxx (Replace xxxx with the GitHub issue number)
- [ ] [Tests added and passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#writing-tests) if fixing a bug or adding a new feature
- [ ] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [ ] Added [type annotations](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#type-hints) to new arguments/methods/functions.
- [ ] Added an entry in the latest `doc/source/whatsnew/vX.X.X.rst` file if fixing a bug or adding a new feature.

The current behavior assumes the `default_category` provided can be coerced to the dtype of the input's columns. When the input's columns labels are strings, and the `default_category` is an integer, currently with object dtype we end up with values that are a mix of strings and integers. With `infer_string=True` where the input's columns are `str` dtype, we end up instead with all strings (coercing the integer to a string).

It's not clear to me whether this case should result in object dtype with a mix of strings and integers, or `str` dtype. Thoughts here are welcome. A few cases to consider are below. Currently I'm going with backwards compatibility, but open to other directions.

```python
df = DataFrame({3: [1, 0, 0], 4: [0, 1, 0]})
result = pd.from_dummies(df, default_category=0.5)
# ValueError: Trying to coerce float values to integers

df = DataFrame({"x": [1, 0, 0], "y": [0, 1, 0]})
result = pd.from_dummies(df, default_category=5)
print(type(result.iloc[2, 0]))
# <class 'int'>
```

Labels:
name: Testing
description: pandas testing functions or related to the test suite
name: Docs
name: Reshaping
description: Concat, Merge/Join, Stack/Unstack, Explode
name: Strings
description: String extension data type and string data

Comments:
@jorisvandenbossche @WillAyd friendly ping
> The current behavior assumes the `default_category` provided can be coerced to the dtype of the input's columns. When the input's columns labels are strings, and the `default_category` is an integer, currently with object dtype we end up with values that are a mix of strings and integers. With `infer_string=True` where the input's columns are `str` dtype, we end up instead with all strings (coercing the integer to a string).
> 
> It's not clear to me whether this case should result in object dtype with a mix of strings and integers, or `str` dtype. Thoughts here are welcome. A few cases to consider are below. Currently I'm going with backwards compatibility, but open to other directions.

This is a tough one but I don't think we should do any special-casing in this method, so should just stick with what the different string types do (even though coercion may not be consistent)
@WillAyd - coming back to this, what do you think of raising? Currently specifying a float when columns are integers raises. My desired behavior with strings would be the same: if you give an integer value and your columns are string dtypes, we should raise.

If we do agree that's what we want, I think we should hold off on this one until 3.0.
Yea generally I think its a good idea to be more strict about the data types, especially with the dedicated string type. So I'd be in favor of raising instead of coercing
can you rebase and ill give this a look
@jbrockmendel - ready now. I reverted this change to just being a small addition to the docs. The one change to the test is just a cleanup, not a change in behavior.
Small question, otherwise LGTM
thanks @rhshadrach