Issue 1:
I am getting an "access to undefined reference" in code that used to work, and that I believe is valid. It takes a very specific combination of details to trigger the problem, so I think it is related to optimization.

As far as I can tell from Travis (assuming they update 0.3 regularly) this behaviour started in the last day or two.

andrew@laptop:~/project/CRC> julia
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: http://docs.julialang.org
_ _ _| |_ __ _ | Type "help()" to list help topics
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.3.0-prerelease+2697 (2014-04-22 02:46 UTC)
_/ |\__'_|_|_|\__'_| | Commit 9dc5e3f* (0 days old master)
|__/ | x86_64-suse-linux

julia> type Single{A}
table::Vector{A}
Single() = new()
end

julia>

julia> function crc(tables=Single)
make_tables(tables{Uint8}())
end
crc (generic function with 2 methods)

julia>

julia> function make_tables(tables::Single)
tables.table = Array(Uint8, 256)
tables.table[1] = 0x0
end
make_tables (generic function with 1 method)

julia>

julia> crc()
ERROR: access to undefined reference
in crc at none:2

I believe this is valid code - undefined members of a type seem to be supported in general, as long as they are created before reading.

Note that much of the "mess" above is necessary in order to trigger this. Below I'll add some minimally modified versions that work to illustrate this:

The type parameterization is needed:

julia> type Single
table::Vector{Uint8}
Single() = new()
end

julia>

julia> function crc(tables=Single)
make_tables(tables())
end
crc (generic function with 2 methods)

julia>

julia> function make_tables(tables::Single)
tables.table = Array(Uint8, 256)
tables.table[1] = 0x0
end
make_tables (generic function with 1 method)

julia>

julia> crc()
0x00

The default argument is needed:

julia> type Single{A}
table::Vector{A}
Single() = new()
end

julia>

julia> function crc(tables)
make_tables(tables{Uint8}())
end
crc (generic function with 1 method)

julia>

julia> function make_tables(tables::Single)
tables.table = Array(Uint8, 256)
tables.table[1] = 0x0
end
make_tables (generic function with 1 method)

julia>

julia> crc(Single)
0x00

The separate routine to set the value is needed:

julia> type Single{A}
table::Vector{A}
Single() = new()
end

julia>

julia> function crc(tables=Single)
t = tables{Uint8}()
t.table = Array(Uint8, 256)
t.table[1] = 0x0
end
crc (generic function with 2 methods)

julia>

julia> crc()
0x00

Finally, the example to cut+paste:

type Single{A}
table::Vector{A}
Single() = new()
end

function crc(tables=Single)
make_tables(tables{Uint8}())
end

function make_tables(tables::Single)
tables.table = Array(Uint8, 256)
tables.table[1] = 0x0
end

crc()

Issue 2:
I'm moving the discussion from JuliaPy/pyjulia#173 to gather more attention. I also describe in the last paragraphs how it may help not only PyJulia users but also other Julia users.

(@stevengj, @Keno, please correct me or add more details if I'm missing something)

Prior to Julia 0.7, PyJulia users could use multiple Python interpreters without rebuilding PyCall.jl (PyJulia depends heavily on PyCall.jl) against each Python interpreters. Considering it's a common practice to have multiple Python virtual environments (with venv/virtualenv/conda), being able to use PyJulia without recompiling PyCall.jl every time is an important feature. However, supporting this feature in Julia ≥ 0.7 seems hard.

(Some details: Just to be clear, not all PyJulia users will notice this effect. Notably, Windows or macOS users only using Python 3 (or only using Python 2...) are unaffected. Linux users only using dynamically linked Python 3 (or 2) are also fine. However, Linux users using statically linked Python, such as the ones distributed by Ubuntu and Anaconda, will not be able to use PyJulia. I think those platforms are popular enough to pay a special attention.)

PyJulia relies on Base.LOAD_CACHE_PATH in Julia 0.6 to separate the cache of PyCall.jl. It inserts a private path to Base.LOAD_CACHE_PATH[1] if the Python interpreter in which PyJulia is loaded is incompatible with the Python interpreter with which PyCall.jl is configured:

# Add a private cache directory. PyCall needs a different
# configuration and so do any packages that depend on it.
self._call(u"unshift!(Base.LOAD_CACHE_PATH, abspath(Pkg.Dir._pkgroot()," +
"\"lib\", \"pyjulia%s-v$(VERSION.major).$(VERSION.minor)\"))" % sys.version_info[0])

--- https://github.com/JuliaPy/pyjulia/blob/18d98e5b1b616a4d663273cc36cdd835ab0b33da/julia/core.py#L357-L360

This "hack" doesn't work in Julia ≥ 0.7 as Base.LOAD_CACHE_PATH is gone now. Also, reading how cache_file_entry is used to locate the .ji files, I couldn't find a way to implement a new "hack" other than duplicating the whole DEPOT_PATH[1].

julia/base/loading.jl

Lines 594 to 608
in
d038f2f

cache_file_entry(pkg::PkgId) = joinpath(

"compiled",

"v$(VERSION.major).$(VERSION.minor)",

pkg.uuid === nothing ? "$(pkg.name).ji" : joinpath(pkg.name, "$(package_slug(pkg.uuid)).ji")

)

function find_all_in_cache_path(pkg::PkgId)

paths = String[]

entry = cache_file_entry(pkg)

for depot in DEPOT_PATH

path = joinpath(depot, entry)

isfile_casesensitive(path) && push!(paths, path)

end

return paths

end

But creating a new DEPOT_PATH[1] for each incompatible Python interpreter type is rather overkill and ignores Pkg3 working hard to de-duplicate resources. It would be really nice to have a direct support from Julia and Pkg3, if it is feasible.

An idea: "build option" support

I think one way to directly support it is to add "build option" support in Julia and Pkg3. What I mean by "build option" is something that altering it changes the precompilation cache. Currently Julia packages do this via environment variables. Concrete examples are PYTHON of PyCall.jl and CONDA_JL_HOME of Conda.jl. If those options can be directly configured by Project.toml file, and if compilation cache paths depend on such options, PyJulia can just create a new Project.toml with appropriate options and launch a new Julia interpreter. Importantly, the compilation cache path of a package has to depend also on the build options of all its (direct and indirect) dependencies.

I think the "build option" support can help other Julia users (who do not use PyJulia) too. For example, you can change CONDA_JL_HOME for a particular Project.toml to tweak versions of external libraries provided via Conda.jl without contaminating other projects. (Maybe similar benefits can be gained via BinaryProvider.jl too?) I think supporting 32-bit and 64-bit Julia JuliaLang/Pkg.jl#93 can also be done by changing "build option" of the "root" julia package. I suppose then it makes sense for deps directories to depend on "build options" too (JuliaLang/Pkg.jl#93 (comment)).