Skip to content

Numeric ranges: how to handle signs, zero, leading zeros? [specification] #371

@cxw42

Description

@cxw42

Edit below under "Update".

I am a relatively new user of editorconfig and have run across something strange. In the Python core, the filename foo0.txt does not match the glob foo{-10..10}.txt. However, the Web page suggests it should:

{num1..num2} Matches any integer numbers between num1 and num2, where num1 and num2 can be either positive or negative.

Test cases

Tested on Cygwin x64 with commit d1b3dd3 of editorconfig-core-py.

Python 2

$ python
Python 2.7.14 (default, Oct 31 2017, 21:12:13)
[GCC 6.4.0] on cygwin
>>> from editorconfig.fnmatch import *
>>> fnmatchcase('foo0.txt','foo{-10..10}.txt')
False

Oops!

>>> fnmatchcase('foo+0.txt','foo{-10..10}.txt')
True
>>> fnmatchcase('foo-0.txt','foo{-10..10}.txt')
True

OK - using an explicit sign makes it match like it should.

>>> fnmatchcase('foo1.txt','foo{-10..10}.txt')
True
>>> fnmatchcase('foo+1.txt','foo{-10..10}.txt')
True
>>> fnmatchcase('foo-1.txt','foo{-10..10}.txt')
True

+1, 1, and -1 all match OK.

Python 3

$ python3
Python 3.6.4 (default, Jan  7 2018, 15:53:53)
[GCC 6.4.0] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from editorconfig.fnmatch import *
>>> fnmatchcase('foo0.txt','foo{-10..10}.txt')
False

Same "oops" as above.

>>> fnmatchcase('foo+0.txt','foo{-10..10}.txt')
True

But with the explicit +0 it matches like it should.

>>> fnmatchcase('foo1.txt','foo{-10..10}.txt')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "editorconfig-core-py/editorconfig/fnmatch.py", line 107, in fnmatchcase
    for (num, (min_num, max_num)) in zip(match.groups(), num_groups):
ValueError: not enough values to unpack (expected 2, got 0)

Double oops! The following also fail with the same traceback:

>>> fnmatchcase('foo-0.txt','foo{-10..10}.txt')
>>> fnmatchcase('foo+1.txt','foo{-10..10}.txt')
>>> fnmatchcase('foo-1.txt','foo{-10..10}.txt')

Thoughts

At least for Py 2, this seems to be related to this, which has an explicit test == '0'. That was part of the commit adding numeric-range support.

Update

I see that glob test braces_numeric_range8 says that 060 should not match {3..120}. Why is that the case? Even if 060 is treated as an octal literal (ugly), decimal 48 = octal 60 is still between decimal 3 and decimal 120. I suspect this test is why the Python core special-cases leading zero.

The only discussion I can find is this comment and the reply - we seem to be following zsh's behaviour rather than the behaviour documented on editorconfig.org/#wildcards (which doesn't mention leading zeros either way). The test was added in this 2014 commit.

Update 2

A use case would be for imagemagick or split -d. Those utilities (and many others) generate sequential files foo00, foo01, ... so that alphabetical/ASCIIbetical sort will leave the files in the proper numeric order. I submit that the glob foo{5..10} should match foo05 through foo10 in order to support that use case.

I also recommend specifying that all numbers are treated as decimal so that 09 is clearly permitted and not treated as an invalid octal number.

I have read the contributing guidelines and the code of conduct. Thanks for looking into this!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions