Re: [gentoo-portage-dev] [PATCH] xattr: centralize the various shims in one place

2013-10-22 Thread Arfrever Frehtes Taifersar Arahesis
2013-10-21 05:00 Mike Frysinger napisał(a):
 On Wednesday 16 October 2013 23:42:26 Arfrever Frehtes Taifersar wrote:
  - cStringIO module should not be used. io module is a replacement available
  since Python 2.6.
 
 unfortunately, that doesn't work as well as it should.  python 2.7's 
 interface 
 is annoyingly different when using other python 2.7 modules.  i'll have the 
 code import the old module and then fallback to using the new io module.

(io.StringIO works only with unicode strings.
When bytes-compatible functions are really needed, then io.BytesIO can be used, 
which works only with bytes.
cStringIO.StringIO is designed to work with bytes, but 
cStringIO.StringIO().write(instance_of_unicode)
implicitly encodes its argument to bytes.)

In your another patch, 
portage.tests.bin.test_prepstrip.PrepStripFull._prepstrip() passes an instance 
of
cStringIO.StringIO class to portage.bin.prepstrip.main(), which passes it to 
portage.bin.prepstrip.Prepstrip(),
which passes it to print(), portage.elog.messages.eqawarn() and 
portage.elog.messages.ewarn().

pym/portage/bin/prepstrip.py should have:
from __future__ import unicode_literals

Then print('...', file=out) calls will work with an instance of io.StringIO 
class.

(portage.elog.messages.eqawarn() and portage.elog.messages.ewarn() internally 
decode message,
so they already work with out=io.StringIO, but not out=io.BytesIO.)

--
Arfrever Frehtes Taifersar Arahesis


signature.asc
Description: This is a digitally signed message part.


Re: [gentoo-portage-dev] [PATCH v2] xattr: centralize the various shims in one place

2013-10-22 Thread Arfrever Frehtes Taifersar Arahesis
2013-10-21 05:07 Mike Frysinger napisał(a):
 Rather than each module implementing its own shim around the various
 methods for accessing extended attributes, start a dedicated module
 that exports a consistent API.
 ---
 v2
   - passes unittests w/python 2.6 2.7 3.2 3.3

But portage.util._xattr._XattrSystemCommands does not work :) .

 import portage.util._xattr
 portage.util._xattr._XattrSystemCommands.list(/tmp)
...

See below.

  bin/xattr-helper.py  |  11 +-
  pym/portage/tests/util/test_xattr.py | 178 ++
  pym/portage/util/_xattr.py   | 205 
 +++
  pym/portage/util/movefile.py | 100 -
  4 files changed, 407 insertions(+), 87 deletions(-)
  create mode 100644 pym/portage/tests/util/test_xattr.py
  create mode 100644 pym/portage/util/_xattr.py
 
 diff --git a/bin/xattr-helper.py b/bin/xattr-helper.py
 index 6d99521..69b83f7 100755
 --- a/bin/xattr-helper.py
 +++ b/bin/xattr-helper.py
 @@ -17,16 +17,7 @@ import re
  import sys
  
  from portage.util._argparse import ArgumentParser
 -
 -if hasattr(os, getxattr):
 -
 - class xattr(object):
 - get = os.getxattr
 - set = os.setxattr
 - list = os.listxattr
 -
 -else:
 - import xattr
 +from portage.util._xattr import xattr
  
  
  _UNQUOTE_RE = re.compile(br'\\[0-7]{3}')
 diff --git a/pym/portage/tests/util/test_xattr.py 
 b/pym/portage/tests/util/test_xattr.py
 new file mode 100644
 index 000..e1f6ee8
 --- /dev/null
 +++ b/pym/portage/tests/util/test_xattr.py
 @@ -0,0 +1,178 @@
 +# Copyright 2010-2013 Gentoo Foundation
 +# Distributed under the terms of the GNU General Public License v2
 +
 +Tests for the portage.util._xattr module
 +
 +from __future__ import print_function
 +
 +try:
 + # Try python-3.3 module first.
 + from unittest import mock
 +except ImportError:
 + try:
 + # Try standalone module.
 + import mock
 + except ImportError:
 + mock = None
 +
 +import subprocess
 +
 +from portage.tests import TestCase
 +from portage.util._xattr import (xattr as _xattr, _XattrSystemCommands,
 + _XattrStub)
 +
 +
 +orig_popen = subprocess.Popen
 +def MockSubprocessPopen(stdin):
 + Helper to mock (closely) a subprocess.Popen call
 +
 + The module has minor tweaks in behavior when it comes to encoding and
 + python versions, so use a real subprocess.Popen call to fake out the
 + runtime behavior.  This way we don't have to also implement different
 + encodings as that gets ugly real fast.
 + 
 + proc = orig_popen(['cat'], stdout=subprocess.PIPE, 
 stdin=subprocess.PIPE)
 + try:
 + proc.stdin.write(bytes(stdin))
 + except TypeError:
 + proc.stdin.write(bytes(stdin, 'ascii'))

It can fail with UnicodeEncodeError.
Use proc.stdin.write(portage._unicode_encode(stdin), 
portage._encodings['stdio']) instead of above 4 lines.

 + return proc
 +
 +
 +class SystemCommandsTest(TestCase):
 + Test _XattrSystemCommands
 +
 + OUTPUT = '\n'.join([
 + '# file: /bin/ping',
 + 'security.capability=0sAQAAAgAgAAA=',
 + 'user.foo=asdf',
 + '',
 + ])
 +
 + def _setUp(self):
 + if mock is None:
 + self.skipTest('need mock for testing')
 +
 + return _XattrSystemCommands
 +
 + def _testGetBasic(self):
 + Verify the get() behavior
 + xattr = self._setUp()
 + with mock.patch.object(subprocess, 'Popen') as call_mock:
 + # Verify basic behavior, and namespace arg works as 
 expected.
 + xattr.get('/some/file', 'user.foo')
 + xattr.get('/some/file', 'foo', namespace='user')
 + self.assertEqual(call_mock.call_args_list[0], 
 call_mock.call_args_list[1])
 +
 + # Verify nofollow behavior.
 + call_mock.reset()
 + xattr.get('/some/file', 'user.foo', nofollow=True)
 + self.assertIn('-h', call_mock.call_args[0][0])
 +
 + def testGetParsing(self):
 + Verify get() parses output sanely
 + xattr = self._setUp()
 + with mock.patch.object(subprocess, 'Popen') as call_mock:
 + # Verify output parsing.
 + call_mock.return_value = MockSubprocessPopen('\n'.join([
 + '# file: /some/file',
 + 'user.foo=asdf',
 + '',
 + ]))
 + call_mock.reset()
 + self.assertEqual(xattr.get('/some/file', 'user.foo'), 
 b'asdf')
 +
 + def testGetAllBasic(self):
 + Verify the get_all() behavior
 + xattr = self._setUp()
 + with