Reviewing this question after much more experience with Python, I came up with one solution, but it violates my then required property, not defining a function.
def make_list_containing(*args): return list(args)
Then make_list_containing(3) or make_list_containing('foo') behaves as you would expect (unlike the list constructor, which you need to modify to find out how to expect it).
It is still surprising to me that list as a constructor is synonymous with "convert to list type" and not "put in an instance of a list object".
I see how the polymorphic behavior of a constructor can be ambiguous in the case of single elements, which are also iterable, like strings. But nevertheless, why not support the "place on the list" behavior for indestructible singletons?
Another thing is that, at least for me, the approach that I am describing seems more consistent and more committed to least surprise.
With make_list_containing you know that you always get the list back and that it will contain the elements that were passed. As long as you transmit them in the format you want, this is exactly what you get out. Consider:
In [34]: make_list_containing(*'foo') Out[34]: ['f', 'o', 'o'] In [35]: make_list_containing('foo') Out[35]: ['foo']
or
In [40]: make_list_containing(*enumerate(range(3))) Out[40]: [(0, 0), (1, 1), (2, 2)] In [41]: make_list_containing(enumerate(range(3))) Out[41]: [<enumerate at 0x7f61a7f0fd70>]
Now it seems to me more intuitive. Providing * is exactly how I should “de-iterate” the elements inside something as arguments. If I don't go out of my way to select this, then I should treat 'foo' as a singleton and plan to handle its elements or iterable myself inside the function call.
One thing that disappoints in this conversation is that just because this Python convention is old people seems to combine this with meaning, this is not surprising. But this is a narrow definition of surprise. Yes, when I start the translator, I am no longer "surprised" when list('foo') gives me ['f', 'o', 'o'] . But I'm still surprised that this language selection interface for the constructor is as important as list . This surprises me, because, it seems, he has more design flaws than strengths, and what was previously used to justify it consisted in some fixation of the smoothness of the syntax, and not in the clarity of thought.
At this point, he is moving too far into the zone of opinions, and I obviously agree that due to the overwhelming historical impulse this will not be changed in Python. But the spirit of my question still concerns this very legitimate moment. This is not a question of "laziness" or "just writing a wrapper function and moving on," as most comments seem to want it to be.