jorgenschaefer / elpy

Emacs Python Development Environment
GNU General Public License v3.0
1.9k stars 262 forks source link

Bug in snippet __init__ when including type annotations #1246

Open gopar opened 6 years ago

gopar commented 6 years ago

Currently if you type __init__ in a buffer you get a nice little snippet that fills up the instance variables with the arguments your passing:

def __init__(self, a, b):
    self.a = a
    self.b = b

But if you include type annotations, it gets all weird:

def __init__(self, a: int, b: str=None):
    self.a: int = a: int
    self.b: str = b: str

The regex from the elpy-snippet-split-args function seems to be the problem.

I tried the following regex on regex101.com and worked but failed when I tried in emacs: [[:blank:]]*:?[\w+]*=[[:blank:]]*

galaunay commented 6 years ago

You have regex-builder (and helm-regexp is you use helm) to help you construct regexp in Emacs. It should be more convenient, as every implementation of regexp (PHP, Python, emacs, java, ...) are slightly different. In the present case, it will show you that Emacs doesn't understand [\w+]* (try \w+ or [[:alphanum:]]+ instead).

I made a few tests and this seems to work:

(defun elpy-snippet-split-args (arg-string)
  "Split a python argument string into ((name, default)..) tuples"
  (mapcar (lambda (x)
            (split-string x "[[:blank:]]*\\(:[[:blank:]]*[[:alpha:]]+\\)?[[:blank:]]*=?[[:blank:]]*" t))
          (split-string arg-string "[[:blank:]]*,[[:blank:]]*" t)))

But maybe it will be cleaner to drop the split-string thing and use proper regex matching.

Thank you for remind me of this Elpy module, very useful !

gopar commented 6 years ago

Thanks, my regex fu is beyond horrible. That does seem rather long though :P

jorgenschaefer commented 6 years ago

rx is also very convenient to construct complex regular expressions. These might be useful to place into global variables, too.