Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

capture: ensure name of EncodedFile being a string #2557

Merged
merged 1 commit into from
Jul 26, 2017

Conversation

blueyed
Copy link
Contributor

@blueyed blueyed commented Jul 5, 2017

Fixes #2555.

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thanks @blueyed!

Could you please also add a new "bugfix" file to the changelog?

@@ -252,6 +252,8 @@ def writelines(self, linelist):
self.write(data)

def __getattr__(self, name):
if name == 'name':
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a small comment here explaining why this special case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do, but it is not really clear to me if this is the way to go after all, since it seems to be only necessary for logging.StreamHandler ?!

@RonnyPfannschmidt
What API where you referring to that says this to be a string?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the overall file.name being a string, IIUC.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm after revisiting, why not just make name a property?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh good idea. 👍

@coveralls
Copy link

Coverage Status

Coverage increased (+0.002%) to 92.14% when pulling 1264971 on blueyed:EncodedFile-name into 7cd03d7 on pytest-dev:master.

@@ -252,6 +252,8 @@ def writelines(self, linelist):
self.write(data)

def __getattr__(self, name):
if name == 'name':
return '{!r}'.format(self.buffer)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This failed in py26 because the field index is mandatory... but I suggest just using repr(self.buffer) as it is shorter and simpler.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, amended.

@blueyed blueyed force-pushed the EncodedFile-name branch from 1264971 to 97bdc6f Compare July 5, 2017 22:12
@coveralls
Copy link

Coverage Status

Coverage increased (+0.002%) to 92.14% when pulling 97bdc6f on blueyed:EncodedFile-name into 7cd03d7 on pytest-dev:master.

@@ -252,6 +252,8 @@ def writelines(self, linelist):
self.write(data)

def __getattr__(self, name):
if name == 'name':
return repr(self.buffer)
return getattr(object.__getattribute__(self, "buffer"), name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while reading, why is get-attribute used there to begin with ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code was already there, I think the idea is that EncodedFile should act as a proxy to the underlying buffer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but then buffer is directly usable to begin with, from my pov that call can very likely be shortened to self.buffer

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OH that! Hmm yeah at first glance you are right, but I suspect this is there for a reason. We would have to hunt the Git history to see if we can find something about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's see if it is covered by some test(s): #2614.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_pickling_and_unpickling_enocded_file fails:

    def test_pickling_and_unpickling_enocded_file():
        # See https://bitbucket.org/pytest-dev/pytest/pull-request/194
        # pickle.loads() raises infinite recursion if
        # EncodedFile.__getattr__ is not implemented properly
        ef = capture.EncodedFile(None, None)
        ef_as_str = pickle.dumps(ef)
>       pickle.loads(ef_as_str)

testing/test_capture.py:1151: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tox/py36/lib/python3.6/site-packages/_pytest/capture.py:258: in __getattr__
    return getattr(self.buffer, name)
.tox/py36/lib/python3.6/site-packages/_pytest/capture.py:258: in __getattr__
    return getattr(self.buffer, name)
.tox/py36/lib/python3.6/site-packages/_pytest/capture.py:258: in __getattr__
    return getattr(self.buffer, name)
E   RecursionError: maximum recursion depth exceeded while calling a Python object
!!! Recursion detected (same locals & position)

@blueyed blueyed force-pushed the EncodedFile-name branch from 97bdc6f to 5c6a4c9 Compare July 25, 2017 13:25
@coveralls
Copy link

Coverage Status

Coverage increased (+0.002%) to 92.058% when pulling 5c6a4c9 on blueyed:EncodedFile-name into 70d9f86 on pytest-dev:master.

@nicoddemus
Copy link
Member

Hmm the check brakes in py26:

___________________________ test_dupfile_on_bytesio ___________________________
    def test_dupfile_on_bytesio():
        io = py.io.BytesIO()
        f = capture.safe_text_dupfile(io, "wb")
        f.write("hello")
        assert io.getvalue() == b"hello"
>       assert f.name.startswith('<_io.BytesIO object at')
E       AssertionError: assert False
E        +  where False = <built-in method startswith of str object at 0x03FB6A88>('<_io.BytesIO object at')
E        +    where <built-in method startswith of str object at 0x03FB6A88> = '<io.BytesIO object at 0x042FCDB0>'.startswith
E        +      where '<io.BytesIO object at 0x042FCDB0>' = <_pytest.capture.EncodedFile object at 0x03C57930>.name

I think changing the assertion to assert "BytesIO object" in f.name would be good enough.

@blueyed blueyed force-pushed the EncodedFile-name branch from 5c6a4c9 to 0603d1d Compare July 25, 2017 18:37
@coveralls
Copy link

Coverage Status

Coverage increased (+0.002%) to 92.058% when pulling 0603d1d on blueyed:EncodedFile-name into 79097e8 on pytest-dev:master.

@nicoddemus
Copy link
Member

Thanks @blueyed!

@nicoddemus nicoddemus merged commit dd294aa into pytest-dev:master Jul 26, 2017
@blueyed blueyed deleted the EncodedFile-name branch July 26, 2017 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants