convert(DateTime, a::String)=parse(DateTime, a) causes causes methoderror in julia

Viewed 56
julia> module a
           using Dates
           import Base.convert
           convert(DateTime, a::String)=DateTime(a, "yyyy-mm-ddTHH:MM:SS.s")
       end
julia> using .a

julia> using Dates
ERROR: MethodError: convert(::Type{Union{RawFD, String}}, ::String) is ambiguous. Candidates:
  convert(DateTime, a::String) in Main.a at REPL[1]:4
  convert(::Type{T}, x::T) where T in Base at essentials.jl:218
Possible fix, define
  convert(::Type{T}, ::String) where T
Stacktrace:
 [1] Base.Filesystem.StatStruct(desc::String, device::UInt32, inode::UInt32, mode::UInt32, nlink::UInt32, uid::UInt32, gid::UInt32, rdev::UInt32, size::UInt64, blksize::UInt64, blocks::UInt64, mtime::Float64, ctime::Float64)
   @ Base.Filesystem ./stat.jl:29
 [2] Base.Filesystem.StatStruct(desc::String, buf::Vector{UInt8})
   @ Base.Filesystem ./stat.jl:61
 [3] stat(path::String)
   @ Base.Filesystem ./stat.jl:154
 [4] isdir(path::String)
   @ Base.Filesystem ./stat.jl:456
 [5] load_path_expand(env::String)
   @ Base ./initdefs.jl:257
 [6] load_path()
   @ Base ./initdefs.jl:320
 [7] Base.LoadingCache()
   @ Base ./loading.jl:230
 [8] require(into::Module, mod::Symbol)
   @ Base ./loading.jl:960

Why this error is occurring? please help. I'm using julia 1.7.2 on linuxmint 20.3. Here adding new method to Base.convert causes method error.

2 Answers

You are committing type piracy here. From the Julia docs:

"Type piracy" refers to the practice of extending or redefining methods in Base or other packages on types that you have not defined. In some cases, you can get away with type piracy with little ill effect. In extreme cases, however, you can even crash Julia

So here you are redefining the convert function, which you haven't defined, for the input types (DataType, String), neither of which you own either. From the stack trace you see that this leads to an ambiguity with another method defined in base, leading to the error.

The type piracy is the important part here, so @NilsGudat's answer addresses the main issue.

However, I was confused at first about how this is an ambiguity, and then realized: when you define convert(DateTime, a::String), DateTime is taken as the name of the argument, not the data type. So Julia sees this definition as a convert method taking one argument called DateTime of type Any, and another argument a::String. That's why there's an ambiguity error printed out. The usual way to define a convert method is to use convert(::Type{TypeToConvertTo}, a::TypeToConvertFrom).

However, even though this was the source of the ambiguity error, the type piracy is the actual problem here. Depending on your needs, you can consider defining a convert_to_datetime(a::String) method instead.

Related