# Module Loading Case Sensitivity on Windows

**URL:** <https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523>\
**Category:** General Usage\
**Tags:** question\
**Created:** [December 10, 2018, 2:11pm UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523 "2018-12-10T14:11:23Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![ReubenHill](https://avatars.discourse-cdn.com/v4/letter/r/4491bb/32.png) [@ReubenHill](https://discourse.julialang.org/u/ReubenHill)\
**Post date:** [December 10, 2018, 2:11pm UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523/1 "2018-12-10T14:11:23Z")

</div>

Hi all,

I’ve had some frustration when trying to load custom modules on Windows. Could someone clarify exactly what the case sensitivity rules are when trying to load modules, and any differences between file systems which are and are not case sensitive?

On Windows 10 (x64), I create the following file

```julia
module MyModule

println("Module loaded!")

end # module

```

and call it `mymodule.jl`. I put it in `C:/Users/MyUserName/Desktop/test`.

Then in the Julia v1.0.2 (x64) REPL I do the below:

```julia
julia> push!(LOAD_PATH,"C:/Users/MyUserName/Desktop/test")
4-element Array{String,1}:
 "@"
 "@v#.#"
 "@stdlib"
 "C:/Users/MyUserName/Desktop/test"

julia> using MyModule
ERROR: ArgumentError: Package MyModule not found in current path:
- Run `import Pkg; Pkg.add("MyModule")` to install the MyModule package.

Stacktrace:
 [1] require(::Module, ::Symbol) at .\loading.jl:823

```

Now I rename the file to `MyModule.jl` and repeat:

```julia
julia> push!(LOAD_PATH,"C:/Users/MyUserName/Desktop/test")
4-element Array{String,1}:
 "@"
 "@v#.#"
 "@stdlib"
 "C:/Users/MyUserName/Desktop/test"

julia> push!(LOAD_PATH,"C:/Users/MyUserName/Desktop/test")
4-element Array{String,1}:
 "@"
 "@v#.#"
 "@stdlib"
 "C:/Users/MyUserName/Desktop/test"

julia> using MyModule
[Info: Recompiling stale cache file C:\Users\MyUserName\.julia\compiled\v1.0\MyModule.ji for MyModule [top-level]
Module loaded!

```

Hooray! Things work.

So questions:

- Is this requirement documented anywhere?
- How does this work if I say, clone someone’s repo who’s been on a case-insensitive filesystem?

The latter seems to be causing my issues. In that case, I think when Git hasn’t been setup to track case changes in file names, custom module loading can sometimes not work for inexplicable reasons.

Thoughts?

---

<div class="post-metadata">

**Author:** ![ReubenHill](https://avatars.discourse-cdn.com/v4/letter/r/4491bb/32.png) [@ReubenHill](https://discourse.julialang.org/u/ReubenHill)\
**Post date:** [May 2, 2019, 5:29pm UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523/2 "2019-05-02T17:29:50Z")

</div>

Hi all, sorry to bump my own post. I’m still having trouble with this. Can anyone help?

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 2, 2019, 5:30pm UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523/3 "2019-05-02T17:30:41Z")

</div>

Can’t you just make the file name match the case of the module?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [May 2, 2019, 6:47pm UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523/4 "2019-05-02T18:47:16Z")

</div>

See [https://github.com/JuliaLang/julia/pull/13542](https://github.com/JuliaLang/julia/pull/13542) … like in Python ([PEP 235](https://www.python.org/dev/peps/pep-0235/)), we decided to make module loading (`using Foo`) case-sensitive on case-insensitive case-preserving filesystems.

> Is this requirement documented anywhere?

This is documented in the manual under [https://docs.julialang.org/en/latest/base/base/#Base.require](https://docs.julialang.org/en/latest/base/base/#Base.require)

> How does this work if I say, clone someone’s repo who’s been on a case-insensitive filesystem?

Virtually all modern filesystems are either case-sensitive or case-insensitive but case-preserving. On the latter (Mac and Windows) systems, the case information is not lost, so you are fine.

Do you have a real need to support source code on case-insensitive case-destroying filesystems?

---

<div class="post-metadata">

**Author:** ![ReubenHill](https://avatars.discourse-cdn.com/v4/letter/r/4491bb/32.png) [@ReubenHill](https://discourse.julialang.org/u/ReubenHill)\
**Post date:** [May 3, 2019, 9:16am UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523/5 "2019-05-03T09:16:08Z")

</div>

Thanks very much for the replies.

> This is documented in the manual under [https://docs.julialang.org/en/latest/base/base/#Base.require](https://docs.julialang.org/en/latest/base/base/#Base.require)

I notice the documentation says

> `require` is case-sensitive on all platforms, including those with  
> case-insensitive filesystems like macOS and Windows.

So to be clear, this is saying that the name of a module must, on such filesystems, match (with case sensitivity) the name of the `.jl` file in which it is created? I wonder if this could be made clearer and put straight into [https://docs.julialang.org/en/latest/manual/modules/](https://docs.julialang.org/en/latest/manual/modules/) ?

> Can’t you just make the file name match the case of the module?

Whilst it’s been a while, I think, when I first created this topic, part of the issue I was having was that _sometimes_ it seemed to matter if the file and module name’s cases matched, and sometimes it didn’t.

It’s not clear to me why, but here are two cases which illustrate the problem (at least on my machine):

On Windows 10 (x64), I create `seqtest.jl` in `C:/Users/MyUserName/Desktop/test`. This contains

```julia
module SeqTest

println("loaded SeqTest")

end # module SeqTest

```

in the same folder I create `procmsgseqtest.jl` which contains

```julia
module ProcMsgSeqTest

println("loaded ProcMsgSeqTest")

end # module ProcMsgSeqTest

```

Then in the Julia v1.0.2 (x64) REPL I do the following:

```julia-repl
julia> push!(LOAD_PATH,"C:\\Users\\MyUserName\\Desktop\\test")
4-element Array{String,1}:
 "@"
 "@v#.#"
 "@stdlib"
 "C:\\Users\\MyUserName\\Desktop\\test"

julia> using SeqTest
ERROR: ArgumentError: Package SeqTest not found in current path:
- Run `import Pkg; Pkg.add("SeqTest")` to install the SeqTest package.

Stacktrace:
 [1] require(::Module, ::Symbol) at .\loading.jl:823

julia> using ProcMsgSeqTest
[Info: Recompiling stale cache file C:\Users\MyUserName\.julia\compiled\v1.0\ProcMsgSeqTest.ji for ProcMsgSeqTest [top-level]
loaded ProcMsgSeqTest

```

Why does it work in one case but not the other? Perhaps someone else could verify on a windows machine?

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 3, 2019, 11:19am UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523/6 "2019-05-03T11:19:00Z")

</div>

> [@ReubenHill](#):
>
> Why does it work in one case but not the other?

We try to enforce that package source file case matches the module case even on case-insensitive file systems to avoid having people develop package on case-insensitive file systems and then have those packages break on case-sensitive file systems. It’s possible that these extra checks are being avoided in one of these cases, but it looks like you’re doing the exact same thing with both of them, so I’m not sure how that’s possible.

Bottom line: the case of the source file that defined a package should match the case of the package name. If there’s a particular place in the docs where you feel like that could be clarified, please do open an issue or better still a pull request proposing such a clarification.

---

<div class="post-metadata">

**Author:** ![ReubenHill](https://avatars.discourse-cdn.com/v4/letter/r/4491bb/32.png) [@ReubenHill](https://discourse.julialang.org/u/ReubenHill)\
**Post date:** [May 3, 2019, 12:56pm UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523/7 "2019-05-03T12:56:39Z")

</div>

As requested! [https://github.com/JuliaLang/julia/pull/31911](https://github.com/JuliaLang/julia/pull/31911)

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [May 3, 2019, 1:46pm UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523/8 "2019-05-03T13:46:35Z")

</div>

> [@StefanKarpinski](#):
>
> We try to enforce that package source file case matches the module case even on case-insensitive file systems

Code loading calls `isfile_casesensitive`, which for Windows is defined as:

```julia
function isfile_casesensitive(path)
    isfile(path) || return false # Fail fast
    basename(Filesystem.longpath(path)) == basename(path)
end

```

`Filesystem.longpath` calls the Win32 function `GetLongPathName` which supposedly returns the case-preserved filename on NTFS.

According to [this write-up](https://weblog.west-wind.com/posts/2007/Dec/06/The-long-Path-to-getting-an-proper-cased-Path-Filename-with-Win32),

> GetLongPathName is specifically meant for 8.3 type paths. So as long as you use 8 character filenames and paths, it will in fact do the right thing.  
> …  
> So a somewhat hacky way to get this to work is to convert the full path to a short path first, then call GetLongPathName with the adjusted path.

So it turns out that case-sensitive check works for `SeqTest` because it is short, whereas `ProcMsgSeqTest` is too long.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [May 3, 2019, 2:04pm UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523/9 "2019-05-03T14:04:05Z")

</div>

[https://media.giphy.com/media/26u8xUlGnEzR4dlzW/giphy.gif(image larger than 4 MB)](https://media.giphy.com/media/26u8xUlGnEzR4dlzW/giphy.gif)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [May 3, 2019, 2:07pm UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523/10 "2019-05-03T14:07:42Z")

</div>

> [@greg\_plowman](#):
>
> So it turns out that case-sensitive check works for `SeqTest` because it is short, whereas `ProcMsgSeqTest` is too long.

Yes, see also this discussion about fixing `realpath`: [inconsistent realpath on Windows · Issue #30588 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/30588#issuecomment-451463656)

We could switch to using `realpath` (which is fixed in Julia 1.2), but I don’t know if that would cause a problem with symlinks on Windows?

---

<div class="post-metadata">

**Author:** ![ReubenHill](https://avatars.discourse-cdn.com/v4/letter/r/4491bb/32.png) [@ReubenHill](https://discourse.julialang.org/u/ReubenHill)\
**Post date:** [May 3, 2019, 2:58pm UTC](https://discourse.julialang.org/t/module-loading-case-sensitivity-on-windows/18523/11 "2019-05-03T14:58:32Z")

</div>

Given this seems to be an issue, I’ve gone ahead and created an issue for this : [https://github.com/JuliaLang/julia/issues/31913](https://github.com/JuliaLang/julia/issues/31913) . I hope that’s useful and doesn’t just split discussion up!
