On Mon, May 13, 2019 at 08:23:34PM +0200, Anders Hovmöller wrote: > > Being found in different modules should always be treated as a sign that > > the functions may be different. (If they're the same, why do we need > > both?) > > Assuming all users know there is another.
How do users know the os module exists in the first place? How do they know to use list.append rather than list += [item]? If you're going to cater only for the most ignorant, know-nothing subset of users, that's an argument against providing *any* functionality at all since they won't know it exists. We ought to assume competent users who know how to *find stuff out* by reading the docs, asking on Stackoverflow or other forums, or by reading other people's code and learning from what they see. > And if you "from x import y" the call site is identical for the two > different functions. This is just asking for trouble. Clearly your threshhold for "trouble" is a lot more sensitive than mine. Using `from module import ...` is always a compromise between verbosity and clarity. We don't want to be like Java: configs.config.server-config.monitoring-service.module-monitoring-levels (I copied that example from the Oracle docs) or even worse. But short names can sometimes be less clear. If the coder is using `from module import` they are explicitly preferring brevity, *and that is okay*. Any even slightly experienced Python programmer will know what to do when you see an unfamiliar function in code: syslink(...) Most of the time we don't need to drill down in fine detail. "It makes symlinks" is enough for us to move on and we really don't want names which explicitly document everything about the function: create_symlink_to_file_on_posix_filesystems_or_windows_vista_or_better_but_not_if_destination_already_exists(...) *wink*. Function names are mnemonics, not documentation. But if you do need to drill down and look at the function in fine detail, we know what to do: look for a local function definition, or a from import, and take it from there. In the worst case, you might have both in the same namespace so you need to resolve which one wins. This is called programming. We all do it. It isn't any trouble except in cases of deliberately or accidently obfuscated code. > >> An optional "overwrite_if_exists=False" flag seems much nicer. > > > > Aside from the argument name being too verbose, that violates the rule > > of thumb "avoid constant bool flags" design principle. > > Verbose is better than cryptic. Having the exact same name as > something that does something else is pretty cryptic. It really isn't. That's why we have namespaces (packages, modules, classes) so we don't have to use unique names for everything. It's not "cryptic" that Paris, France is difference from Paris, Texas. Let's not abuse the word "cryptic" for things which are easy to resolve. This is cryptic: https://britishlibrary.typepad.co.uk/digitisedmanuscripts/2015/08/help-us-decipher-this-inscription.html not having two symlink functions in different modules. > Then a different name seems also to be in order. symlink/setsymlink > seems a lot better to me for example. "set" adds nothing to the function name that isn't already implied. You might as well just prefix it with any random three characters: symlink # sets a symlink gwqsymlink # sets a symlink Among those who don't read the docs, all you are doing is giving them three extra characters to type when they post to Stackoverflow: "What's the difference between os.symlink and shutil.[set]symlink?" Arguably "forcesymlink" or "force_symlink" would be better, but given that option, I'd flip my preference to a force parameter: +1 shutil.symlink +0 os.symlink with force=False parameter -0.5 shutil.force_symlink -1 shutil.setsymlink -- Steven _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/