# Include command inconsistent with isfile result

**URL:** <https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578>\
**Category:** General Usage\
**Created:** [July 20, 2019, 10:51am UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578 "2019-07-20T10:51:33Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 20, 2019, 10:51am UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/1 "2019-07-20T10:51:33Z")

</div>

I am having trouble to include a file. More precisely `isfile(fi)` returns true, but `include(fi)` errors  
`ERROR: LoadError: could not open file C:\temp\a\SomePackage\src\src\file.jl`

I created an MWE here.  
I simply run `julia --startup-file=no --track-allocation=user mwe_include_error.jl` in PowerShell (from the src directory)

> **[GitHub - kafisatz/MWE\_include\_error](https://github.com/kafisatz/MWE_include_error)**
>
> Contribute to kafisatz/MWE\_include\_error development by creating an account on GitHub.

Is this expected not to work?  
It is quite irritating that `isfile` returns true, but the include command fails.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [July 20, 2019, 11:04am UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/2 "2019-07-20T11:04:51Z")

</div>

You example works for me:

```julia
julia> include(fi)
hello there

```

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 20, 2019, 11:13am UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/3 "2019-07-20T11:13:32Z")

</div>

Are you on Windows?  
Any idea why it fails for me?

 ![image](https://global.discourse-cdn.com/julialang/original/3X/a/4/a4768b1817efa2c1ef5f59daddd6c6e5a300c1d8.png)

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 20, 2019, 11:14am UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/4 "2019-07-20T11:14:43Z")

</div>

have you actually done the same call (i.e. run julia with the argument mwe\_include\_error.jl)?

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [July 20, 2019, 11:46am UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/5 "2019-07-20T11:46:33Z")

</div>

No, I didn’t, I get the same as you. From the docstring of `include`:

```julia
  include(path::AbstractString)

  Evaluate the contents of the input source file in the global scope
  of the containing module. Every module (except those defined with
  baremodule) has its own 1-argument definition of include, which
  evaluates the file in that module. Returns the result of the last
  evaluated expression of the input file. During including, a task-local
  include path is set to the directory containing the file. Nested calls to
  include will search relative to that path. This function is typically
  used to load source interactively, or to combine files in packages
  that are broken into multiple source files.

  Use Base.include to evaluate a file into another module.

```

I guess what is happening here is that when you execute `julia file.jl` there will be a nested include, and when you include from file.jl paths are relative that file.

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 20, 2019, 11:54am UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/6 "2019-07-20T11:54:44Z")

</div>

I would vote for include and isfile to be consistent in the way that relative paths are resolved.  
Would you agree?

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [July 20, 2019, 12:11pm UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/7 "2019-07-20T12:11:48Z")

</div>

Nah, you probably want the current behavior. You can work with absolute paths instead of relative paths.

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 20, 2019, 12:34pm UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/9 "2019-07-20T12:34:42Z")

</div>

Well is there an easy way to make the path absolute?  
Notably I am handing the same argument (a relative path) to isfile and include. But it is treated differently.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [July 20, 2019, 12:36pm UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/10 "2019-07-20T12:36:43Z")

</div>

```julia
help?> abspath

  abspath(path::AbstractString) -> AbstractString

  Convert a path to an absolute path by adding the current directory
  if necessary. Also normalizes the path as in normpath.

```

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 21, 2019, 8:46am UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/11 "2019-07-21T08:46:56Z")

</div>

thanks this works.

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 21, 2019, 8:49am UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/12 "2019-07-21T08:49:14Z")

</div>

> [@fredrikekre](#):
>
> I guess what is happening here is that when you execute `julia file.jl` there will be a nested include, and when you include from file.jl paths are relative that file.

I did not execute julia file.jl  
I ran ` julia --startup-file=no .\mwe_include_error.jl`  
Have you tried that?

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [July 21, 2019, 10:58am UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/13 "2019-07-21T10:58:49Z")

</div>

`file.jl` was just a placeholder.

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [July 21, 2019, 12:45pm UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/14 "2019-07-21T12:45:14Z")

</div>

I feel like your “model” is a little wrong. Normally julia files are in specific locations. So if a file does:

```julia
include("../file1.jl")

```

It expects to find file1.jl in the parent directory of the currently executing file…not in the parent directory of the current path. Otherwise one file changing the current directory would break all the includes for other files. i.e. If someone did this:

```julia
main.jl:
    include("f1.jl")
    include("f2.jl")
    include("f3.jl")
f1.jl:
    cd("c:\\")
f2.jl
   cd("c:\\temp")
f3.jl:
  println("hello")

```

This would just not work **unless** `main.jl` knows that `f1.jl` will change the directory, and that `f2.jl` will also change the directory. What it would create is a nightmare of “file not found” situations where you are going to have to display the current directory before every include just to make sure the current directory is what you _expected_ before you do the include.

I would suggest looking into `include_string` where the file can be loaded first with something like `read(filename, String)` then passed to `include_string`. By using `read` the found/not found behavior of `isfile` will match with `read`.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 21, 2019, 1:04pm UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/15 "2019-07-21T13:04:54Z")

</div>

I think you missed the fact that `include` operates relative to `@ __DIR__ `, which has nothing to do with the “current directory”, which is essentially a global state. Cf

```nohighlight
$ pwd
/home/tamas

$ cat /tmp/test.jl 
@info "working directory" pwd()
@info "directory of file" @ __DIR__

$ julia /tmp/test.jl
┌ Info: working directory
└ pwd() = "/home/tamas"
┌ Info: directory of file
└ #= /tmp/test.jl:2 =# @ __DIR__ = "/tmp"

```

As explained by @pixel27, conflating the two would have obvious disadvantages — global state should be avoided unless absolutely necessary.

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 21, 2019, 1:50pm UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/16 "2019-07-21T13:50:52Z")

</div>

So let’s say I have a number of functions (readdlm, writedlm, CSV.read, isfile, include, rm, …).  
Is there an easy way to find out whether these work relative to „current dir“ or `@ __DIR__ `?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 21, 2019, 2:02pm UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/17 "2019-07-21T14:02:48Z")

</div>

I think that basically everything that uses [built-in I/O](https://docs.julialang.org/en/v1/base/io-network/) (think of `open`) will resolve paths relative to the current directory if necessary, but relying on this is not very good style.

You should always provide full paths if possible. If you are loading a lot of files from your package directory, it is worth it to define something like

```julia
project_path(parts...) = normpath(joinpath(@ __DIR__ , "..", parts...))

```

in one of the files in `src/` and then use it to construct paths.

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [July 21, 2019, 7:10pm UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/18 "2019-07-21T19:10:31Z")

</div>

Thank you.  
I think my confusion was ‘initiated’ by the fact that I have used the include command in an interactive VS Code session. In that case, I think, the include function is not relative to the file its in (as there is no such file), but relative to the working dir.

---

<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:** [July 21, 2019, 8:26pm UTC](https://discourse.julialang.org/t/include-command-inconsistent-with-isfile-result/26578/19 "2019-07-21T20:26:52Z")

</div>

Only code loading (`include`) is relative to the current source file. Everything else is a normal file operation and works relative to the current working directory.
