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

Tracking non-.jl source files #680

Merged
merged 11 commits into from
Jul 30, 2022
Merged

Tracking non-.jl source files #680

merged 11 commits into from
Jul 30, 2022

Conversation

oscardssmith
Copy link
Contributor

This PR removes the requirement that file be a ::AbstractString which makes it possible to teach Revise about non-julia source files by making your own file type (eg PyFile).

src/pkgs.jl Outdated Show resolved Hide resolved
@KristofferC
Copy link
Collaborator

It would be good to document what are the exact methods one need to overload in order to hook up a custom file format to Revise. And then to finish it off, add a test as well.

@KristofferC KristofferC closed this May 2, 2022
@KristofferC KristofferC reopened this May 2, 2022
@KristofferC
Copy link
Collaborator

(fatfingered the close button)

@oscardssmith
Copy link
Contributor Author

oscardssmith commented May 2, 2022

Should I add a section to the developer reference with details on how to do this?

@KristofferC
Copy link
Collaborator

I think that is a good place, yes.

@oscardssmith
Copy link
Contributor Author

oscardssmith commented May 2, 2022

Just so I don't forget, here is a relatively minimal example of using this feature

struct MyFile
    file::String
end
Base.abspath(file::MyFile) = MyFile(Base.abspath(file.file))
Base.isfile(file::MyFile) = Base.isfile(file.file)
Base.isabspath(file::MyFile) = Base.isabspath(file.file)
Base.findfirst(str::String, file::MyFile) = Base.findfirst(str, file.file)
Base.String(file::MyFile) = file.file

function make_module(file::MyFile)
    exprs = []
    for line in eachline(file.file)
       val, name = split(line, '=')
       push!(exprs, :($(Symbol(name)) = $val))
    end
    Expr(:toplevel, :(module test
       $(exprs...)
    end), :(using .test))
end

function Base.include(mod::Module, file::MyFile)
    Core.eval(mod, make_module(file))
end
Base.include(file::MyFile) = Base.include(Core.Main, file)
using Revise
function Revise.parse_source!(mod_exprs_sigs::Revise.ModuleExprsSigs, file::MyFile, mod::Module; kwargs...)
    ex = make_module(file)
    @show mod_exprs_sigs, file, mod, kwargs
    Revise.process_source!(mod_exprs_sigs, ex, file, mod; kwargs...)
end
function Revise.is_same_file(a::MyFile, b::String)
    a.file == b
end
function Revise.is_same_file(b::String, a::MyFile)
    a.file == b
end

m=MyFile("test.program")
includet(m)

@oscardssmith
Copy link
Contributor Author

@KristofferC can you re-run CI?

@oscardssmith
Copy link
Contributor Author

for reference, this depends on timholy/CodeTracking.jl#95

@oscardssmith
Copy link
Contributor Author

@timholy bump on this? What are your thoughts?

Copy link
Owner

@timholy timholy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems fine in principle, with the major concern being timholy/CodeTracking.jl#95 (comment).

Briefly, is the idea that this tracks changes in, e.g., Python code as you develop? Wouldn't you be testing the Python code in Python first? I'm a bit confused about exactly how this will be handy (not doubtful, just confused).

test/fake_lang/non_jl_test.jl Outdated Show resolved Hide resolved
topmod = first(keys(mexsold))
fileok = file_exists(filep)
fileok = file_exists(String(filep))
Copy link
Owner

@timholy timholy Jun 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're doing it this way, any reason not to use string instead of String? Conversely, to insulate this from invalidation, String(filep)::String might be necessary.

@oscardssmith
Copy link
Contributor Author

The use case for this is in X->julia transpilers. Revising the foreign code is useful because it allows you to use the Julia repl (including debugger.jl) as a repl for non julia source code which can be very useful especially when X is a language that doesn't have good tooling (hence why you are writing a transpiler in the first place). This wouldn't be that useful for Python or other major languages (they tend to be big and have good tooling anyway), but for small languages that traditionally don't have good tooling (i.e. C/BrainFuck/random proprietary languages people wrote in the 80s)

Copy link
Owner

@timholy timholy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mostly looks good. I'm proposing a couple of changes to decrease the risk of invalidation of Revise's own code when people load packages.

We do need the test working before we can merge this. I think you also need to run this test from runtests.jl?

test/fake_lang/non_jl_test.jl Outdated Show resolved Hide resolved
src/parsing.jl Outdated Show resolved Hide resolved
test/fake_lang/non_jl_test.jl Outdated Show resolved Hide resolved
src/parsing.jl Show resolved Hide resolved
@oscardssmith
Copy link
Contributor Author

One complication here is that these tests won't pass until timholy/CodeTracking.jl#95 is merged and tagged.

src/packagedef.jl Outdated Show resolved Hide resolved
Keno and others added 2 commits July 26, 2022 11:31
Update src/pkgs.jl

Co-authored-by: Kristoffer Carlsson <kcarlsson89@gmail.com>

add docs

add non_julia program

Create non_jl_test.jl

Update types.jl

Update types.jl

simplify

simplify requirements.

update docs

update test

Create new_test.program

test revising

Update test/fake_lang/non_jl_test.jl

Co-authored-by: Tim Holy <tim.holy@gmail.com>

fix typo in tests

test fake_lang

update tests
@oscardssmith
Copy link
Contributor Author

Invalidations fixed. Tests pass (with the codetracking PR+Julia1.7. On 1.9, the tests fail with or without this PR, but including my test file passes).

Copy link
Owner

@timholy timholy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There still seems to be some unnecessary invalidation risk here. Realized invalidations depend on which package you load; you might try InlineStrings.jl as a package that defines a lot of new string types and methods, e.g.,

using SnoopCompileCore
using Revise    # Revise precompiles a lot, so you're probably OK, otherwise force a revision to make sure everything is compiled before the next step
invs = @snoopr using InlineStrings
using SnoopCompile
trees = invalidation_trees(invs)

src/packagedef.jl Outdated Show resolved Hide resolved
src/packagedef.jl Outdated Show resolved Hide resolved
src/packagedef.jl Outdated Show resolved Hide resolved
src/packagedef.jl Outdated Show resolved Hide resolved
src/parsing.jl Outdated Show resolved Hide resolved
@oscardssmith
Copy link
Contributor Author

apologies. the things I resolved were changes that I made that I then lost while rebasing (and didn't check)

oscardssmith and others added 3 commits July 29, 2022 08:51
Co-authored-by: Tim Holy <tim.holy@gmail.com>
Co-authored-by: Tim Holy <tim.holy@gmail.com>
Co-authored-by: Tim Holy <tim.holy@gmail.com>
test/non_jl_test.jl Outdated Show resolved Hide resolved
Co-authored-by: Tim Holy <tim.holy@gmail.com>
@timholy
Copy link
Owner

timholy commented Jul 30, 2022

That fixed the first path issue but there are more. Presumably it fails locally in the same way with Pkg.test()?

@oscardssmith
Copy link
Contributor Author

No, this is passing locally (even if I don't run the tests from the Revise folder).

test/non_jl_test.jl Outdated Show resolved Hide resolved
Co-authored-by: Sebastian Pfitzner <pfitzseb@gmail.com>
@timholy
Copy link
Owner

timholy commented Jul 30, 2022

OK. Then try the same trick with all the rest of your paths?

@timholy
Copy link
Owner

timholy commented Jul 30, 2022

You have another one on line 42?

test/non_jl_test.jl Outdated Show resolved Hide resolved
Co-authored-by: Sebastian Pfitzner <pfitzseb@gmail.com>
@pfitzseb
Copy link
Collaborator

Non-nightly tests seem to pass now.

@timholy timholy merged commit 2de4173 into timholy:master Jul 30, 2022
@oscardssmith oscardssmith deleted the kf/nonjl branch July 31, 2022 00:24
@oscardssmith
Copy link
Contributor Author

Thanks so much!

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.

5 participants