Skip to content

mcabbott/Compat.jl

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Compat Package for Julia

Build Status Build status

The Compat package is designed to ease interoperability between older and newer versions of the Julia language. In particular, in cases where it is impossible to write code that works with both the latest Julia master branch and older Julia versions, or impossible to write code that doesn't generate a deprecation warning in some Julia version, the Compat package provides a macro that lets you use the latest syntax in a backwards-compatible way.

This is primarily intended for use by other Julia packages, where it is important to maintain cross-version compatibility.

Usage

To use Compat in your Julia package, add a line Compat to the REQUIRE file in your package directory. Then, in your package, shortly after the module statement include lines like these:

using Compat
import Compat.String

and then as needed add

@compat ...compat syntax...

wherever you want to use syntax that differs in the latest Julia master (the development version of Julia). The compat syntax is usually the syntax on Julia master. However, in a few cases where this is not possible, a slightly different syntax might be used. Please check the list below for the specific syntax you need.

Supported syntax

Currently, the @compat macro supports the following syntaxes:

  • @compat foo(::CartesianRange{N}) to replace the former foo(::CartesianRange{CartesianIndex{N}}) (#20974). Note that CartesianRange now has two type parameters, so using them as fields in other structs requires manual intervention.

  • Required keyword arguments (#25830). For example, @compat foo(; x, y) makes x and y required keyword arguments: when calling foo, an error is thrown if x or y is not explicitly provided.

Module Aliases

  • using Compat.Test, using Compat.SharedArrays, using Compat.Mmap, and using Compat.DelimitedFiles are provided on versions older than 0.7, where these are not yet part of the standard library. (#23931)

  • using Compat.Base64 is provided on versions older than 0.7, where this library is not yet a part of the standard library. (#24361)

  • using Compat.Dates is provided on versions older than 0.7, where this library is not yet a part of the standard library. (#24459)

  • using Compat.Unicode is provided on versions older than 0.7, where this library is not yet a part of the standard library. (#25021)

  • using Compat.Printf is provided on versions older than 0.7, where this library is not yet a part of the standard library. (#25056)

  • using Compat.SparseArrays is provided on versions older than 0.7, where this library is not yet part of the standard library (#25249).

  • using Compat.LinearAlgebra is provided on versions older than 0.7, where this library is not yet part of the standard library (#25571).

  • using Compat.Random is provided on versions older than 0.7, where this library is not yet part of the standard library (#24874).

  • using Compat.Libdl is provided on versions older than 0.7, where this library is not yet part of the standard library (#25459).

  • using Compat.REPL is provided on versions older than 0.7, where this library is not yet part of the standard library (#25544).

  • using Compat.Serialization is provided on versions older than 0.7, where this library is not yet part of the standard library (#25628).

  • using Compat.Distributed is provided on versions older than 0.7, where this library is not yet part of the standard library (#24443).

  • using Compat.Pkg is provided on versions older than 0.7, where this library is not yet part of the standard library (#25705). Note that Compat.Pkg will point to the new package manager on 0.7 which does not have a fully compatible API with the old package manager.

  • using Compat.InteractiveUtils is provided on versions older than 0.7, where this library is not yet part of the standard library (#25780).

  • using Compat.LibGit2 is provided on versions older than 0.7, where this library is not yet part of the standard library (#25706).

  • using Compat.UUIDs is provided on versions older than 0.7, where this library is not yet part of the standard library (#25819).

  • using Compat.Markdown is provided on versions older than 0.7, where this library is not yet part of the standard library (#25738).

  • using Compat.Sockets is provided on versions older than 0.7, where this library is not yet part of the standard library (#25935)

  • using Compat.Statistics is provided on versions older than 0.7, where this library is not yet part of the standard library (#27834).

New functions, macros, and methods

  • eachrow, eachcol, and eachslice to iterate over first, second, or given dimension of an array (#29749).

  • isnothing for testing if a variable is equal to nothing (#29674).

  • Compat.readline with keep keyword argument (#25646)

  • Compat.eachline with keep keyword argument (#25646)

  • Compat.readuntil with keep keyword argument (#25646)

  • The isabstract, parameter_upper_bound, typename reflection methods were added in Julia 0.6. This package re-exports these from the Compat.TypeUtils submodule. On earlier versions of julia, that module contains the same functions, but operating on the pre-0.6 type system representation.

  • Compat.invokelatest supports keywords (#22646).

  • @__MODULE__ is aliased to current_module() for Julia versions 0.6 and below. Versions of Base.binding_module, expand, macroexpand, and include_string were added that accept a module as the first argument. (#22064)

  • Cmd elements can be accessed as if the Cmd were an array of strings for 0.6 and below (#21197).

  • Val(x) constructs Val{x}(). (#22475)

  • The reshape and ntuple APIs are extended to support Val{x}() arguments on 0.6 and below.

  • logdet for Numbers (#22629).

  • fieldcount is equivalent to nfields for Julia versions 0.6 and below and is used to determine the number of fields in a data type (#22350).

  • There are versions of InexactError, DomainError, and OverflowError that take the same arguments as introduced in Julia 0.7-DEV (#20005, #22751, #22761).

  • Base.rtoldefault how takes a third parameter atol. The two argument form is deprecated in favor of the three arguments form with atol=0.

  • The corrected optional argument of cov becomes a keyword argument of Compat.Statistics.cov (#21709).

  • isequal, == and in have one argument "curried" forms. For example isequal(x) returns a function that compares its arguments to x using isequal (#26436).

  • *(::Union{Char,AbstractString},::Union{Char,AbstractString}) concatenation. (#22512)

  • diagm and spdiagm accept pairs mapping diagonals to vectors (#24047, #23757)

  • Constructors for Matrix{T}, Array{T}, and SparseMatrixCSC{T} from UniformScaling (#24372, #24657)

  • Constructor for Matrix from UniformScaling (#24372, #24657).

  • UndefInitializer and undef with corresponding Array constructors (#24652, #26316).

  • BitArray constructors for undef (#24785, #26316).

  • @compat finalizer(func, obj) with the finalizer to run as the first argument and the object to be finalized as the second (#24605).

  • IOContext accepting key-value Pairs (#23271).

  • pairs for iterating over key-value Pairs (#22907).

  • get do-block syntax supported when using ENV (#23412).

  • Some{T} wraps T to signify that a result of T<:Void is expected (#23642).

  • replace accepts a pair of pattern and replacement, with the number of replacements as a keyword argument (#25165).

  • CartesianIndices and LinearIndices types represent cartesian and linear indices of an array (respectively), and indexing such objects allows translating from one kind of index to the other (#25113).

  • codeunits(s) returns an array-like view of the UInt8 code units of a string and ncodeunits(s) returns the number of code units (#25241). codeunit(s) returns the type of the code units of s (#24999).

  • thisind(s, i) returns the character index for codeunit i (#24414).

  • Three-argument methods prevind(s,i,n), nextind(s,i,n) (#23805), and length(s,i,j) (#24999); the latter two replace chr2ind and ind2chr in Julia 0.7, respectively.

  • printstyled prints to a given stream optionally in color and/or bolded (#25522).

  • Dates.Period rounding (e.g., round(Dates.Hour(36), Dates.Day, RoundNearestTiesUp) == Dates.Day(2) (#24182).

  • firstindex to obtain the first index of an iterable (#25458).

  • Compat.names supporting keyword arguments for all and imported (#25647).

  • Compat.IOBuffer supporting keyword arguments (#25873).

  • Compat.range supporting positional and keyword arguments flavors (#25896), (#28708).

  • Compat.trunc, Compat.floor, Compat.ceil, Compat.round, take a keyword argument for base and digits, Compat.round also takes sigdigits (#26156, #26670).

  • Compat.mv and Compat.cp with force keyword argument (#26069).

  • Compat.accumulate, Compat.accumulate!, Compat.all, Compat.any, Compat.cumprod, Compat.cumprod!, Compat.cumsum, Compat.cumsum!, Compat.findmax, Compat.findmin, Compat.mapreduce, Compat.maximum, Compat.Statistics.mean, Compat.Statistics.median, Compat.minimum, Compat.prod, Compat.reduce, Compat.sort, and Compat.sum with dims keyword argument (#25989,#26369).

  • Compat.mapreduce and Compat.reduce with init keyword argument (#27711).

  • selectdim to obtain a view of an array with a specified index for a specified dimension (#26009).

  • Compat.cat with dims as keyword argument (#27163)

  • Single-argument permutedims(x) for matrices and vectors (#24839).

  • fetch for Tasks (#25940).

  • Compat.qr takes pivot as a Val instance (#22475).

  • Compat.Sys.which and Compat.Sys.isexecutable (#26559, #27298).

  • Compat.rmul! provides a subset of the functionality of LinearAlgebra.rmul! for use with Julia 0.6 (#25701, #25812).

  • isbits(t::Type) is now isbitstype(t) (#26850).

  • something to get the first argument different from nothing, unwrapping those of the Some type (#27258).

  • mapslices with dims keyword argument (#27828).

  • hasproperty and hasfield (#28850). hasproperty is defined only for Julia 0.7 or later.

  • merge methods with one and n NamedTuples (#29259).

Renaming

  • Display is now AbstractDisplay (#24831).

  • reprmime(mime, x) is now repr(mime, x) (#25990) and mimewritable is now showable (#26089).

  • is_apple, is_bsd, is_linux, is_unix, and is_windows are now Sys.isapple, Sys.isbsd, Sys.islinux, Sys.isunix, and Sys.iswindows, respectively. These are available in the Compat.Sys submodule. (#22182)

  • readstring is replaced by methods of read. (#22864)

    read(::IO, ::Type{String}), read(::AbstractString, ::Type{String}), and read(::AbstractCmd, ::Type{String}) are defined for 0.6 and below.

  • Range is now AbstractRange (#23570)

  • select* functions (select, select!, selectperm, selectperm!) are renamed to partialsort* (partialsort, partialsort!, partialsortperm, partialsortperm!) (#23051)

  • ctranspose and ctranspose! are now adjoint and adjoint! (#23235)

  • Math constants (π, pi, e, γ, eulergamma, catalan, φ, golden) are moved to the MathConstants module (available as Compat.MathConstants). The name exported from Base for e is changed to . (#23427)

  • IntSet is now BitSet (#24282)

  • strwidth and charwidth are now merged into textwidth (#23667).

  • Complex32, Complex64, and Complex128 are now ComplexF16, ComplexF32, and ComplexF64, respectively (#24647).

  • trace is now tr, available as Compat.tr (#26365).

  • JULIA_HOME is now Sys.BINDIR, available in the Compat.Sys submodule. (#25102)

  • Associative is now AbstractDict (#25012).

  • indices is now axes (#25057). This function is not exported from Compat to avoid conflicts with AxisArrays and other such packages.

  • Void is now Nothing with an alias Cvoid for C interop (#25162).

  • unshift! and shift! are now pushfirst! and popfirst! (#25100).

  • Base.IteratorSize and Base.IteratorEltype are available as Compat.IteratorSize and Compat.IteratorEltype (#25402).

  • copy! and unsafe_copy! are now copyto! and unsafe_copyto! (#24808).

  • contains(haystack, needle) is now occursin(needle, haystack) (#26283). occursin also has a new method for Char needles (#22435).

  • ismatch(r::Regex, str::AbstractString, offset=0) is now occursin(r, str) and occursin(r, str, offset = offset) respectively (#24673,#26283).

  • ipermute! is now invpermute! (#25168).

  • module_parent, Base.function_module, and Base.datatype_module are now methods of a new function called parentmodule (#25629).

  • module_name, Base.function_name, and Base.datatype_name are now methods of a new function called nameof (#25622).

  • find is now findall (#25545).

  • search is now findfirst/findnext and rsearch is now findlast/findprev, sometimes combined with isequal or in (#24673, #26436).

  • Compat.findfirst, Compat.findnext, Compat.findlast and Compat.findprev, return nothing when no match is found (rather than 0 or 0:-1) as on Julia 0.7 (#24673, #26149).

  • findin(a, b) is now findall(in(b), a) (#24673).

  • indmin and indmax are now argmin and argmax, respectively (#25654).

  • Compat.indexin accepts any iterable as first argument, returns nothing (rather than 0) for entries with no match and gives the index of the first (rather than the last) match (#25662, #25998).

  • isabstract and isleaftype are now isabstracttype and isconcretetype, respectively (#23666, #25496).

  • gc and gc_enable are now GC.gc and GC.enable, respectively (#25616).

  • endof is now lastindex (#25458). (Note that lastindex(A, n) is not supported.)

  • nb_available is now bytesavailable (#25634).

  • method_exists is now hasmethod (#25615).

  • object_id is now objectid (#25615).

  • DevNull, STDIN, STDOUT and STDERR are now devnull, stdin, stdout and stderr respectively (#25959).

  • LinSpace is now LinRange (#25896).

  • isupper, islower, ucfirst and lcfirst are now isuppercase, islowercase, uppercasefirst and lowercasefirst (#26442).

  • Compat.split and Compat.rsplit accept keepempty keyword argument if splitter is given as second argument (#26634)

  • isalpha is now isletter (#27077).

  • cfunction is now @cfunction (#26486).

  • Unicode.isnumeric is now available as isnumeric (#25479).

  • vecnorm and vecdot are now Compat.norm and Compat.dot, respectively, while the old norm(A::AbstractMatrix, p=2) is now Compat.opnorm (#27401). import Compat: ⋅ to get Compat.dot as the binary operator .

  • atan2 is now a 2-argument method of atan (#27253).

  • srand is now Compat.Random.seed! (#28295)

  • realmin and realmax are now floatmin and floatmax (#28302)

  • squeeze is now dropdims (#28303, #26660).

  • repmat is now repeat (#26039)

New macros

  • @nospecialize has been added (#22666).

  • The logging macros @error, @warn, @info and @debug can be used as Compat.@error, Compat.@warn, Compat.@info and Compat.@debug on Julia 0.6 (#24490). Note that the behavior do not mirror the logging macros in Julia 0.7, instead on Julia 0.6:

    • Messages are printed to STDERR (like info and warn on Julia 0.6) and not to a dedicated logging stream.
    • The loglevel can not be controlled, but Compat.@debug messages can be turned on/off by calling Compat.enable_debug(true/false).
    • Extra metadata sent to the macros are ignored.

    As an alternative, see the MicroLogging.jl package for a logging interface similar to the one in Julia 0.7.

Other changes

  • On versions of Julia that do not contain a Base.Threads module, Compat defines a Threads module containing a no-op @threads macro.

  • The Expr(:macrocall) has an extra initial argument __source__, which can be tested for with Compat.macros_have_sourceloc.

New types

  • Compat.AbstractDateTime is an alias for Compat.Dates.AbstractDateTime as of (#25227) and Compat.Dates.TimeType prior to that.

Developer tips

One of the most important rules for Compat.jl is to avoid breaking user code whenever possible, especially on a released version.

Although the syntax used in the most recent Julia version is the preferred compat syntax, there are cases where this shouldn't be used. Examples include when the new syntax already has a different meaning on previous versions of Julia, or when functions are removed from Base Julia and the alternative cannot be easily implemented on previous versions. In such cases, possible solutions are forcing the new feature to be used with qualified name in Compat.jl (e.g. use Compat.<name>) or reimplementing the old features on a later Julia version.

If you're adding additional compatibility code to this package, the contrib/commit-name.sh script in the base Julia repository is useful for extracting the version number from a git commit SHA. For example, from the git repository of julia, run something like this:

bash $ contrib/commit-name.sh a378b60fe483130d0d30206deb8ba662e93944da
0.5.0-dev+2023

This prints a version number corresponding to the specified commit of the form X.Y.Z-aaa+NNNN, and you can then test whether Julia is at least this version by VERSION >= v"X.Y.Z-aaa+NNNN".

Tagging the correct minimum version of Compat

One of the most frequent problems package developers encounter is finding the right version of Compat to add to their REQUIRE. This is meant to be a guide on how to specify the right lower bound.

  • Find the appropriate fix needed for your package from the Compat README. Every function or feature added to Compat is documented in its README, so you are guaranteed to find it.

  • Navigate to the blame page of the README by clicking on the README file on GitHub, and then clicking on the blame button which can be found in the top-right corner.

  • Now find your fix, and then find the corresponding commit ID of that fix on the left-hand side. Click on the commit ID. This navigates to a page which recorded that particular commit.

  • On the top pane, you should find the list of the tagged versions of Compat that includes this fix. Find the minimum version from there.

  • Now specify the correct minimum version for Compat in your REQUIRE file by Compat <version>

About

Compatibility across Julia versions

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Julia 100.0%