Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add function Sys.username() #51897

Merged
merged 3 commits into from
Nov 2, 2023
Merged

add function Sys.username() #51897

merged 3 commits into from
Nov 2, 2023

Conversation

barucden
Copy link
Contributor

The commit introduces a new function to Base which returns the current user's username retrieved from the password database.

Resolves #48302
Closes #48928

base/env.jl Outdated Show resolved Hide resolved
@JeffFessler
Copy link
Contributor

Looks terrific! Thanks for taking the lead on this.

@PallHaraldsson
Copy link
Contributor

PallHaraldsson commented Oct 27, 2023

In case of a name conflict, one needs to prefix the reference (Base.symbol) to get the Base definition.

Continuing discussion here. I think you're actually right, but I'm thinking also, would username() you are defining be likely used in Packages (and assuming they do unprefixed, since they think ok, because it's exported)? Let's assume such a case: I'm not sure what happens if you import a package, and define your own username(), maybe you did that long ago, now adding a dependency, will you redefine username() that the package is using to use your definition? I'm not sure it will happen, but if, then this is a breaking change (or a potential footgun for users).

If this is possible, then there are also other changes that might help. Packages are precompiled, and I'm not sure I want it possible that they get changed under your feet. If you use e.g. Python, then I think you can redefine pretty much anything, as in Julia, it's an even more dynamic language, but if you're calling precompiled packages, as often done for speed, then it's just not technically possible to change them, you could need a C compiler. Possibly that can and should happen with Julia precompiled packags, that you can't redefine (also would get rid of invalidations?).

@JeffFessler
Copy link
Contributor

I don't know the answers to @PallHaraldsson' questions precisely, but the general concern about name conflicts would seem to apply to proposals to add any new functions to Julia. Yet additions are being made; for example stack was added in 1.9: https://docs.julialang.org/en/v1/base/arrays/#Base.stack
The name stack is just as generic as username so it is likely to have existed in some other packages/code.

@barucden
Copy link
Contributor Author

barucden commented Oct 27, 2023

Oh, I see. If a user uses a package that already exports username then there will be a problem. I think.

Edit: Such packages exist (at least one): https://github.com/JuliaParallel/Elly.jl/blob/f906ac53b35ff42f51857a18d21f7336fe579816/src/Elly.jl#L29

@stevengj
Copy link
Member

We don't consider exporting new functions to be breaking changes IIRC.

base/env.jl Outdated Show resolved Hide resolved
test/env.jl Outdated Show resolved Hide resolved
test/env.jl Outdated Show resolved Hide resolved
@barucden
Copy link
Contributor Author

The Windows CI finished successfully. The failing tests are unrelated.

@PallHaraldsson
Copy link
Contributor

Since you actually added to Libc, should maybe NOT export from Base, since not needed, i.e. Libc.username() would work, and this wouldn't be used much anyway?

I'm thinking exporting from Base could always be added later, and I still have concerns about it:

We don't consider exporting new functions to be breaking changes IIRC.

That is perfectly fine to do from e.g. Libc or any non-Base module. Are you sure there are no practical implications for Base, and also that thought ok. I seem to recall a doc PR suggesting changes to regarding using in practice i.e. proposing NOT exporting from packages. It seems like the same issue, I just haven't tracked that PR down.

the general concern about name conflicts would seem to apply to proposals to add any new functions to Julia.

No, but yes, from Base, since using it is implicit. We get away with it if functions aren't conflicting in practice.

As annoying as fully qualifying is, it's the norm in e.g. Python, and after namspaces in C++, for some reason e.g. cout that used to work needs to be std::cout, so I think they have thought this through, that it might be better.

@barucden
Copy link
Contributor Author

Since you actually added to Libc

I put it to the Libc submodule because that's where the Cpasswd structure is defined.

should maybe NOT export from Base,

I don't know. If username is supposed to be a part of the user-facing API, then I'd say it should be exported. If it is not supposed to be a part of the user-facing API, then there is little reason to add it at all because it is not used anywhere in Base.

Anyway, I do not feel qualified to be the judge of that. I'll update the PR to whatever the maintainers suggest.

@PallHaraldsson
Copy link
Contributor

If username is supposed to be a part of the user-facing API

It still would be, we now have the new public keyword for that, to make it clear. It would be documented, and if you worry about it not being seen or overlooked in the docs, then yes, I do not find ?malloc with help, unless I do ?Libc.malloc, but maybe that should be changed. I think the help should find all public, also from Libc or stdlibs not yet imported. The help text should then add, "In Libc, so needs to be prefixed with Libc."

It's not possible to unexport later, or it would be a breaking change, but adding an export from Base could always be added.

Do you think this function would be frequently used? And do you think it would never be a problem/conflict with exporting (even for packages)?

@stevengj
Copy link
Member

Libc.username seems like an odd place for this, since Libc exports generally correspond directly to low-level libc functions, and this is not such a function.

@barucden
Copy link
Contributor Author

Libc also defines getpid or gethostname though. But I don't mind moving username elsewhere. Do you have any suggestion?

@PallHaraldsson
Copy link
Contributor

PallHaraldsson commented Oct 31, 2023

Those are actually defined in C standard library(?), and thus Libc (and also exported from Base...). [Possibly getppid should be added there too.]

A better precident as exceptions would be FormatError and GetLastErro (only defined in Windows):

https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror

I suggested in Libc, since to get the username, as a string, it seemed to actually need to use Libc, to get user id, so at least related, if I recall. I admit it may be less discoverable. I would also be ok with unexported, but marked public, as Base.getusername. It's best if we chose wisely which prefix to not need to allow both... I'm assuming stuff in Base needs not be in the sysimage... I don't like it bloated for startup cost reasons, not just for name-space pollution.

@stevengj
Copy link
Member

stevengj commented Oct 31, 2023

I think we should just export it from Base, analogous to homedir(). We've allowed new exports in Julia minor versions many times already.

Actually, a better possibility might be to put it in the Sys module, as Sys.username() (not exported from Base, but still documented).

@JeffFessler
Copy link
Contributor

I'll upvote Sys.username and I am fine with no export.
Right now Sys is a funny collection of very low-level stuff like cpu_info and very high level stuff like isunix
https://github.com/JuliaLang/julia/blob/master/base/sysinfo.jl
so it might not be where people would look first for username but as long as it is documented it can be found there.

(In my dreams I would type user<tab> at the REPL and it would offer me the option of Sys.username.)

@barucden
Copy link
Contributor Author

barucden commented Nov 1, 2023

Alright, I moved the user-facing function to Sys. Libc now defines getpw which is the lower-level function.

@PallHaraldsson
Copy link
Contributor

I'm ok with merging as is since this does what the title says (after it's changed from Base: -> Sys:)

I saw this was marked as a "good first issue". I hope I didn't make it too hard on you... :)

One question though on the new getpw, though, should it be exported like others, e.g. gethostname? And I' not sure it makes a difference, since it will be used as Libc.getpw. So what is the exporting for there, all under Libc, need qualifying already?! If it's just to signal part of the API, then the new public keyword is for that, and could alternatively be used.

I see it uses a subset of the full struct, and maybe that's an argument for keeping NOT part of the API?

@barucden
Copy link
Contributor Author

barucden commented Nov 1, 2023

I saw this was marked as a "good first issue". I hope I didn't make it too hard on you... :)

All good. It is not my first PR too.

One question though on the new getpw, though, should it be exported like others, e.g. gethostname?

I do not think it should be exported. It is almost the same as getpwuid, which is not exported.

base/sysinfo.jl Outdated Show resolved Hide resolved
base/libc.jl Outdated Show resolved Hide resolved
base/libc.jl Outdated Show resolved Hide resolved
NEWS.md Outdated Show resolved Hide resolved
The commit introduces a new function to `Base.Sys` which returns the
current user's username retrieved from the password database.

Resolves JuliaLang#48302
Closes JuliaLang#48928

Co-authored-by: Steven G. Johnson <stevenj@mit.edu>
@stevengj stevengj changed the title Base: add function username add function Sys.username() Nov 1, 2023
@barucden
Copy link
Contributor Author

barucden commented Nov 1, 2023

Thank you. I squashed all the commits, updated the docs (username -> Sys.username), and rebased to master.

The PR should be ready for merging after CI finishes.

base/sysinfo.jl Outdated Show resolved Hide resolved
Co-authored-by: Jameson Nash <vtjnash@gmail.com>
@vtjnash vtjnash added the merge me PR is reviewed. Merge when all tests are passing label Nov 1, 2023
base/sysinfo.jl Outdated Show resolved Hide resolved
Co-authored-by: Jameson Nash <vtjnash@gmail.com>
@vtjnash vtjnash merged commit 54996ca into JuliaLang:master Nov 2, 2023
2 checks passed
@giordano giordano removed the merge me PR is reviewed. Merge when all tests are passing label Nov 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

username() function (analogous to homedir())
6 participants