Offer option to clear screen after earch rerun
Hello @olzhasar. First of all, thanks for your contribution, its really handy.
I'd suggest a little modification at the function
def _run_pytest(args) -> None:
subprocess.run(["pytest", *args])
To something like
def _run_pytest(args, clear=False) -> None:
if clear:
subprocess.run(["clear"])
subprocess.run(["pytest", *args])
To clear the results before each test.
Thanks!!
Hey @estevaoem, Thank you for your feedback and this suggestion!
I agree that clearing the screen can be really useful, but I am not sure if this can be achieved that easily and will work on all systems. I will take a time to evaluate possible ways to implement this.
Appreciate your idea!
Yeah, true. I was doing some tests with subprocess.run(["clear"]) on docker and found that the TERM env var should be present on the container for it to work and I didnt find time yet to learn more about it. I'll come back here if I find something userfull to contribute. You can close the issue if you will 😂
@olzhasar @estevaoem
Use os.system instead of subprocess.run
ipython (license BSD-3) has across-platform clear screen, ipython.utils.terminal::_term_clear():
if os.name == 'posix':
def _term_clear():
os.system('clear')
elif sys.platform == 'win32':
def _term_clear():
os.system('cls')
else:
def _term_clear():
pass
Used in its demo.
@estevaoem Interested in making a PR so we can demo it?
Edit (2022-10-30): Updated ipython links 8.2.0 -> 8.6.0
@tony Thanks for providing this snippet.
This approach looks good to me, but why do you think we need to use os.system? Does it have any advantages over subprocess.run in this case?
why do you think we need to use
os.system? Does it have any advantages oversubprocess.runin this case?
I have no opinion on it, only since it was ipython's approach and they're widely used: so I expect it's robust.
@tony, currently I'm using the following solution:
ptw --runner "pytest --picked --testmon ./test"
with the following libraries for testing:
pyparsing==3.0.9
attrs==21.4.0
py==1.11.0
iniconfig==1.1.1
packaging==21.3
pluggy==1.0.0
pytest==7.1.2
pytest-testmon==1.3.4
colorama==0.4.5
coverage==6.4.2
docopt==0.6.2
pytest-picked==0.4.6
watchdog==2.1.9
pytest-watch==4.2.0
pytest-cov==3.0.0
pytest-mock==3.8.2
any updates?
May i propose a tricky solution, Ansi escape sequence:
- the
2Jto erase the entire screen - the
Hto put the cursor at0,0position - and a
end=""to not ouput a new line
this can be summurized with print("\x1b[2J\x1b[H", end=""), tested on Windows 11 and Ubuntu 23.04 working great. since MacOS is *nix like this should also work :)
any updates?
I suspect the reason this issue is (and might stay) off the radar despite being marked as good first issue is that it requires testing on three separate platforms, which not everyone can do. @Pixailz did you try that in a throwaway script or a fork of pytest-watcher? If the latter I'd be happy to do more testing on Linux, and perhaps others can chime in for other platforms.
I currently do not have much time to implement this. Will hopefully be able to work on that next month. In the meantime, PRs are welcome.
@bard The tricky part for me is testing on Windows machines, cause I personally don't use one. Another thing is testing for different terminal emulators on Linux, MacOS.
@Pixailz looks quite hacky, will probably be hard to maintain that in future. But I appreciate the suggestion
@olzhasar not that much, it's a specification to manipulate the terminal, this link easily show what's possible with ANSI Escaped Sequence. In fact that's just a sequence of character printed out to the terminal, and the terminal interpret those as "command", and it's pretty universal
to be honest i don't how to put this little print("\x1b[2J\x1b[H", end=""), but i'd be happy to make PR for you to test.
a little script to see if it work on OS's is available here
The OG pytest-watch package had a -c option which was providing that functionality. Maybe it's worth checking out the implementation.
@aaaaahaaaaa Good idea. Just to save people some hunting:
is_windows = sys.platform == 'win32'
# ...
def clear():
"""
Clears the terminal.
"""
subprocess.call('cls' if is_windows else 'clear', shell=True)
https://github.com/joeyespo/pytest-watch/blob/17375a1cf5be6d4dd30a583ffad61a0083d91b94/pytest_watch/helpers.py#L28C66-L28C66
ANSI escape codes were specified in 1976 in the ECMA-48 standard, that's nearly 48 years ago, it's a pretty safe bet that it will be easy to support them for that many more years to come. Sending those escape codes is exactly what clear does (check out clear | hexdump -C), but it's much more efficient to do it directly.
The ones used in the snippet are called Erase Display and CUrsor Position, see wikipedia.
A new version with clear screen support has just been released.
I ended up using the \033c sequence. It appears that it achieves the same result as the one suggested by @Pixailz, but is more concise.
Thank you everyone for your suggestions!