libpython-clj icon indicating copy to clipboard operation
libpython-clj copied to clipboard

py. syntax is doing weird things with the clj-kondo linter

Open sstraust opened this issue 1 year ago • 6 comments

The linter is doing something weird, because it assumes that py/py. is actually a reference to the symbol "py/py" with no ".".

I'm unable to write a custom :lint-as for this, because clj-kondo doesn't consider the possibility that "py." could represent a macro. ingoring :unresolved-var doesn't quite fill my usecase, as I want to remove the red squiglies under the second argument of the py. call as well.

I think clj-kondo is technically in the right here, because py. isn't supported clojure syntax, although I do like the py. notation, and it'd be nice if it was supported. I don't ask to change the notation, but it'd be nice to have a workaround that fixes these tooling issues.

https://clojure.org/reference/reader#_reader_forms

Symbols beginning or ending with '.' are reserved by Clojure.

Great Library! -- Sammy

sstraust avatar Dec 08 '24 01:12 sstraust

Could you provide a specific example? :)

jjtolton avatar Dec 08 '24 13:12 jjtolton

I'm not sure how to like, give the right context since I'm not an expert in the underlying libs, but here are a few screenshots

Screenshot 2024-12-08 at 11 04 32 AM Screenshot 2024-12-08 at 11 05 43 AM

as well as a minimum working example to explain the behavior

(defmacro py.
  {:clj-kondo/lint-as 'clj-kondo.lint-as/def-catch-all}
  [x method-name & args]
  ;; method-name cast to a string specifically for go and go-loop
  ;; compatability
  `(~#'$a ~x ~(str method-name) ~@args))

(defmacro py2
  {:clj-kondo/lint-as 'clj-kondo.lint-as/def-catch-all}
  [x method-name & args]
  ;; method-name cast to a string specifically for go and go-loop
  ;; compatability
  `(~#'$a ~x ~(str method-name) ~@args))


(py. client test)  ;; clj-kondo returns an error, because it doesnt recognize py.
(py2 client test)  ;; clj-kondo does not return an error

sstraust avatar Dec 08 '24 16:12 sstraust

It's because clj-kondo has re-written the parser as opposed to using Clojure's compiler itself so its order of evaluation is different than clojure's in terms of macros vs normal forms - https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7509.

The work around is to not use the py. syntax I think and just write out the expression in terms of (-> get-attr get-attr call-attr ) etc.

We have a previous issue about this if you want to look at it. The gist is (py.) makes sense to python users and does what they expand and we could see other things such as (r. ) or (julia.) etc in the general case of inter-language interop -- something they had no consideration of when writing that document.

cnuernber avatar Dec 08 '24 16:12 cnuernber

Yep, it's unfortunate. Looks like some of the offending lines may be here here where they have hard-coded lack of support.

As @cnuernber mentioned, regarding:

https://clojure.org/reference/reader#_reader_forms

Symbols beginning or ending with '.' are reserved by Clojure.

This is not at odds with the py. syntax -- what Clojure chooses to support and not is effectively arbitrary, in this case. If Clojure chose to support it, then it would be supported. There's no reason, for instance, (:require-python ...) could not be included as part of the ns macro, (or the ns macro could be made extensible).

I would suggest filing an issue with clj-kondo, @sstraust. At first there might be some pushback, but if enough people request it, they may change eventually :)

At this point, thousands if not 10's of thousands of people use libpython-clj -- @sstraust I'm sure you're not the only person with this issue.

jjtolton avatar Dec 08 '24 17:12 jjtolton

Can anyone check whether this issue is fixed in the latest commit of clj-kondo? borkdude just pushed a fix for this issue.

amano-kenji avatar Apr 06 '25 14:04 amano-kenji

@amano-kenji wow I'm just seeing this, that's great news!!

jjtolton avatar Nov 05 '25 01:11 jjtolton