Skip to content

shlex have problems with parsing unicode #45511

Closed

Description

@dexen
mannequin
BPO 1170
Nosy @loewis, @rhettinger, @mdickinson, @abalkin, @orsenthil, @vstinner, @benjaminp, @mcepl, @ezio-melotti, @merwok, @dhellmann, @bitdancer, @jewettaij
Dependencies
  • bpo-10587: Document the meaning of str methods
  • Files
  • shlex-unicode.patch
  • issue1170.diff: py3k patch
  • shlex_wt.py: shlex augmented with "wordterminators" member
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2021-09-20.07:18:12.357>
    created_at = <Date 2007-09-17.15:53:56.721>
    labels = ['type-bug', 'docs']
    title = 'shlex have problems with parsing unicode'
    updated_at = <Date 2021-09-29.07:33:59.402>
    user = 'https://bugs.python.org/dexen'

    bugs.python.org fields:

    activity = <Date 2021-09-29.07:33:59.402>
    actor = 'jewett-aij'
    assignee = 'none'
    closed = True
    closed_date = <Date 2021-09-20.07:18:12.357>
    closer = 'vstinner'
    components = ['Documentation']
    creation = <Date 2007-09-17.15:53:56.721>
    creator = 'dexen'
    dependencies = ['10587']
    files = ['9025', '18224', '23161']
    hgrepos = []
    issue_num = 1170
    keywords = ['patch']
    message_count = 51.0
    messages = ['55967', '55968', '55969', '58964', '77972', '77973', '91853', '106424', '109292', '110854', '110856', '111594', '111709', '111710', '111716', '111717', '111718', '111719', '111751', '111755', '111756', '112911', '122919', '122929', '140227', '140246', '140262', '140516', '140518', '140529', '140586', '140590', '140591', '140592', '144074', '144076', '144077', '144080', '144097', '144193', '144201', '144202', '146219', '146220', '348612', '402187', '402200', '402821', '402822', '402824', '402825']
    nosy_count = 19.0
    nosy_names = ['loewis', 'rhettinger', 'mark.dickinson', 'belopolsky', 'orsenthil', 'vstinner', 'dexen', 'benjamin.peterson', 'cgwalters', 'mcepl', 'ezio.melotti', 'eric.araujo', 'doughellmann', 'r.david.murray', 'nwerneck', 'fperez', 'Santiago.Romero', 'wombat', 'jewett-aij']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue1170'
    versions = ['Python 3.5']

    Activity

    1. added
      stdlibStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or error
      on Sep 17, 2007
    2. dexen commented on Sep 17, 2007

      dexenmannequin
      MannequinAuthor

      Feeding unicode to shlex object created in POSIX compat mode causes
      UnicodeDecodeError to be raised. It appears that shlex object defines
      sting .wordchars, containing latin-1 (iso8859-1) encoded characters
      with charcodes >=128, which is used to check whether a character from
      input constitues a word character or not.

    3. dexen commented on Sep 17, 2007

      dexenmannequin
      MannequinAuthor

      A quick paste to illustrate: the exception is raised only when unicode
      object is passed to shlex. Warning: the cStringIO module is unsuitable
      for use there, only the StringIO. cStringIO does not output unicode.

      dexen!muraena!~$ python
      Python 2.5.1 (r251:54863, May  4 2007, 16:52:23)
      [GCC 4.1.2] on linux2
      Type "help", "copyright", "credits" or "license" for more information.
      >>> from StringIO import StringIO
      >>> import shlex
      >>> lx = shlex.shlex( StringIO( unicode( "abc" ) ) )
      >>> lx.get_token()
      u'abc'
      >>> lx = shlex.shlex( StringIO( unicode( "abc" ) ), None, True )
      >>> lx.get_token()
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "/usr/lib/python2.5/shlex.py", line 96, in get_token
          raw = self.read_token()
        File "/usr/lib/python2.5/shlex.py", line 150, in read_token
          elif nextchar in self.wordchars:
      UnicodeDecodeError: 'ascii' codec can't decode byte 0xdf in position 
      63: ordinal not in range(128)
      >>>
    4. dexen commented on Sep 17, 2007

      dexenmannequin
      MannequinAuthor

      One remark to previous message:
      the first time i created shlex object in non-POSIX mode (the default),
      in later it's in POSIX mode (due to the third parameter to shlex being
      True). The bug in question manifests only in POSIX mode.

      BTW, that so-called POSIX mode would be more POSIX-ish, if instead of
      comparing characters with a fixed, short list, would use the ctype()
      function as found in standard C library. The functions takes current
      locale (setable in process) into account when deciding what is leter,
      whitespace, punctuation etc.

    5. cgwalters commented on Dec 22, 2007

      cgwaltersmannequin
      Mannequin

      Patch to add Unicode support.

      Note: this patch recodes shlex.py from iso-8859-1 to utf-8, so it has
      mixed encodings.

    6. nwerneck commented on Dec 17, 2008

      nwerneckmannequin
      Mannequin

      Hello. I tried to patch my own shlex, and this doens't seem to be
      working properly. When I try the patched module isntead of th eoriginal,
      in my otherwise working program, I get the result ahead.

      Is there any conversion steps missing?...

      mymachine$ python interp.py < exemplo.prg
      Traceback (most recent call last):
        File "interp.py", line 11, in <module>
          tok = ss.get_token()
        File "shlexutf.py", line 103, in get_token
          raw = self.read_token()
        File "shlexutf.py", line 139, in read_token
          nextcategory = unicodedata.category(nextchar)
      TypeError: category() argument 1 must be unicode, not str
    7. nwerneck commented on Dec 17, 2008

      nwerneckmannequin
      Mannequin

      OK, it worked after I found out I didn't know how to open unicode
      files... Sorry for the noise, and thanks for this patch! :]

    8. benjaminp commented on Aug 22, 2009

      @benjaminp
      Contributor

      The patch needs tests before it can be applied. Additionally, I'm not
      sure if having a "utf" option is helpful. Is there a reason not to have
      unicode support by default?

    9. merwok commented on May 25, 2010

      @merwok
      Member

      shlex in 3.x works with Unicode strings. Is it still time to try to fix this bug for 2.7?

    10. bitdancer commented on Jul 5, 2010

      @bitdancer
      Member

      shlex may use unicode in py3k, but since the file still starts with a latin-1 coding cookie and the posix logic hasn't been changed, I suspect that it does not work correctly (ie: does not correctly identify word characters, per msg55969).

      It's too late for 2.7 I think, but it seems there is work still to do in py3k.

    11. abalkin commented on Jul 20, 2010

      @abalkin
      Member

      As discussed in msg110828 under bpo-9308, it is not clear whether logic identifying word characters in shlex is correct in presence of unicode.

    12. self-assigned this
      on Jul 20, 2010
    13. abalkin commented on Jul 20, 2010

      @abalkin
      Member

      I believe the e-mail thread that culminated in r32284, "Implemented posix-mode parsing support in shlex.py", was "shellwords" from April 2003:
      http://mail.python.org/pipermail/python-dev/2003-April/034670.html

      I scanned through the messages, but could not find a reference to the standard that was implemented.

    14. 33 remaining items

    15. bitdancer commented on Sep 17, 2011

      @bitdancer
      Member

      Ezio, I don't see any indication in this ticket that this bug was actually *fixed* in 3.x. Unicode doesn't cause immediate errors in 3.x, but it isn't recognized as wordchars, etc. Am I missing something?

    16. ezio-melotti commented on Sep 17, 2011

      @ezio-melotti
      Member

      I haven't looked at the shlex code (yet), my comment was just about the idea of adding constants with chars that belong to different Unicode categories.

    17. merwok commented on Oct 23, 2011

      @merwok
      Member
      $ ./python 
      Python 2.7.2+ (2.7:27ae7d4e1983+, Oct 23 2011, 00:09:06) 
      [GCC 4.6.1] on linux2
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import shlex
      >>> shlex.split(u'Hello, World!')
      ['Hello,', 'World!']

      This bug was fixed indirectly by a StringIO fix in 27ae7d4e1983, for bpo-1548891. BTW, this report was a duplicate of bpo-6988, closed a year ago.

      Python 2.7.3 will finally support unicode in shlex, so the doc change requested in this report is outdated. However, I still want to do something for this. I’ve noticed that shlex.split’s argument can be a file-like object, and I wonder if passing a StringIO.StringIO(my_unicode_string) wouldn’t work. If such a short recipe works, I’m all for including it in the 2.7 docs for users of older versions. If a longer recipe is needed, then ActiveState’s Python Cookbook would be more appropriate, and I’ll add a link to the docs. If it’s very long and requires a PyPI project, then I’m willing to link to that.

    18. merwok commented on Oct 23, 2011

      @merwok
      Member

      The second message in this page reports that StringIO.StringIO works, but when I pass a unicode string with non-ASCII chars there’s a method call that fails because of implicit unicode-to-str conversion:

      Traceback (most recent call last):
        File "/usr/lib/python2.7/shlex.py", line 150, in read_token
          elif nextchar in self.wordchars:
      UnicodeDecodeError: 'ascii' codec can't decode byte 0xdf in position 63: ordinal not in range(128)

      I’ll try to create a Shlex instance, replace self.wordchars with a decoded version and try again.

    19. removed their assignment
      on Jun 30, 2014
    20. vstinner commented on Jul 29, 2019

      @vstinner
      Member

      This issue is 12 years old has 3 patches: it's far from being "newcomer friendly", I remove the "Easy" label.

    21. mcepl commented on Sep 19, 2021

      mceplmannequin
      Mannequin

      I cannot reproduce it with the current 3.* version. Did anybody reproduce with 3.5?

      Otherwise, I suggest close this, as a 2.* bug.

    22. vstinner commented on Sep 20, 2021

      @vstinner
      Member

      This issue has been fixed in Python 3 by using Unicode rather than bytes in shlex. Python 2 users: it's time to upgrade to Python 3 ;-)

    23. jewettaij commented on Sep 29, 2021

      jewettaijmannequin
      Mannequin

      The error messages may have gone away, but the underlying unicode limitations I mentioned remain:

      Suppose you wanted to use shlex to build a parser for Chinese text. Would you have to set "wordchars" to a string containing every possible Chinese character?

      I myself wrote a parser for a crude language where words can contain any character except for whitespace and parenthesis. I needed a way to specify the characters which cannot belong to a word. (That's how I solved the problem. I modified shlex.py and added a "wordterminators" member. If "wordterminators" was left blank, then "wordchars" were used instead. This was a trivial change to "shlex.py" and it added a lot of functionality.)

      I would like to suggest making this change (or something similar) to the official version of "shlex.py". Would sending an email to "[email protected]" be a good place to make this proposal?

    24. vstinner commented on Sep 29, 2021

      @vstinner
      Member

      I would like to suggest making this change (or something similar) to the official version of "shlex.py". Would sending an email to "[email protected]" be a good place to make this proposal?

      Yes, python-ideas is a good place to start discussion such idea. This issue is closed, if you discuss it here, you will get a limited audience.

    25. jewettaij commented on Sep 29, 2021

      jewettaijmannequin
      Mannequin

      After posting that, I noticed that the second example I listed in my previous post (a language where words contain any non-whitespace, non-parenthesis character) can now be implemented in the current version of shlex.py by setting ​"whitespace_true" and "punctuation". (Sorry, it's been a while since I looked at shlex.py, and it's had some usefl new features.)

    26. jewettaij commented on Sep 29, 2021

      jewettaijmannequin
      Mannequin

      Alright. I'll think about it a little more and post my suggestion there, perhaps. Thanks Victor.

    27. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      docsDocumentation in the Doc dirtype-bugAn unexpected behavior, bug, or error

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions