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

[jarun#704] fixed Windows support #705

Merged
merged 1 commit into from
Dec 8, 2023
Merged

Conversation

LeXofLeviafan
Copy link
Collaborator

@LeXofLeviafan LeXofLeviafan commented Dec 5, 2023

fixes #704:

  • fixing error caused by I/O stream manipulation in browse(url) on Windows 11

also:

  • fixing color support on Windows 7-10
  • fixing tests to work on Windows (full tox run now succeeds on Windows 7-11… though I'm not actually sure how exactly this works on Windows 7 considering that it's no longer supported by CPython 3.9+ 😅)
  • fixing unregistered Pytest marker warning when running tests in Tox
  • fixing deprecation warning for text argument of BeatifulSoup .find*() methods

@@ -4721,6 +4721,8 @@ def browse(url):
# Found a GUI browser, suppress browser output
browse.suppress_browser_output = True
break
if sys.platform == 'win32': # GUI apps have no terminal IO on Windows
browse.suppress_browser_output = False
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Terminal I/O implementation on Windows forces the app to spawn a terminal window for it to actually make any I/O at all; due to this, I/O streams are disabled in pretty much all Windows applications with GUI.

…And manipulating I/O streams somehow breaks console process handle on Windows 11 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Also, in theory it should be possible to avoid I/O streams manipulation by setting browser.redirect_output & browser.background to True, but a quick practical test showed me that it's ridiculously easy to get a browser instance where this simply doesn't work :-/

except ImportError:
import pyreadline3 as readline # type: ignore
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

pyreadline3 (…and incidentally pyreadline as well) actually exports a readline module, so this fallback export is both redundant and useless.

try:
import readline
import colorama
colorama.just_fix_windows_console() # noop on non-Windows systems
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ANSI colour codes are disabled by default on Windows 7-10, but are fairly easy to turn on.

This does not affect non-Windows systems, by design.

@@ -3570,7 +3570,7 @@ def import_html(html_soup: BeautifulSoup, add_parent_folder_as_tag: bool, newtag
comment_tag = tag.findNextSibling('dd')

if comment_tag:
desc = comment_tag.find(text=True, recursive=False)
desc = comment_tag.find(string=True, recursive=False)
Copy link
Collaborator Author

@LeXofLeviafan LeXofLeviafan Dec 5, 2023

Choose a reason for hiding this comment

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

text parameter was renamed to string in BeautifulSoup 4.4.0 due to confusing semantics.

The deprecation warning was added in 4.11.0 to prevent usage of text as a keyword parameter.

[pytest]
markers =
non_tox: not run on tox

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

pytest.ini doesn't seem to be used when running tests via Tox. This appears to fix the “non-registered marker” warning.

@@ -56,13 +60,13 @@ commands =
pytest --cov buku -vv -m "not non_tox" {posargs}

[testenv:pylint]
basepython = py311
basepython = {env:BASEPYTHON:py311}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Windows doesn't seem to support Python detection correctly (likely due to not having a fixed file structure).

This allows to override configured Python version with an env variable.

@@ -0,0 +1,2 @@
@if not defined BASEPYTHON set BASEPYTHON=python
@tox.exe %*
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

On Windows only, running tox (with or without arguments) will default to this script, which ensures that BASEPYTHON is set (using the python executable of the venv, or the one in PATH if not using venvs for some reason)

for bdb in bdbs:
try:
bdb.cur.close()
bdb.conn.close()
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Most of the tests in this file fail on Windows due to DB connection not being closed between tests (since it causes DB file deletion to fail).

@pytest.fixture()
def setup():
def bukuDb():
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Changing this fixture to a ‘managed’ BukuDB spawner, that ensures all connections are closed at the end of the test.

def _bukuDb(*args, **kwargs):
nonlocal bdbs
bdbs += [BukuDb(*args, **kwargs)]
return bdbs[-1]
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Alternatively this could be implemented as a class with BukuDb() method, but this way seems less clunky.

return bdbs[-1]

yield _bukuDb
rmdb(*bdbs)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is run after the test is completed

)
home = os.path.expanduser("~")
dbdir_local_expected = (os.path.join(home, ".local", "share", "buku") if sys.platform != 'win32' else
os.path.join(home, "AppData", "Roaming", "buku"))
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

On Windows, the default folder for application data is C:\%USERPROFILE%\AppData\Roaming\

@@ -124,7 +144,7 @@ def test_get_default_dbdir(self):
# -- home is defined differently on various platforms.
# -- keep a copy and set it back once done
originals = {}
for env_var in ["HOME", "HOMEPATH", "HOMEDIR"]:
for env_var in ["HOME", "HOMEPATH", "HOMEDIR", "APPDATA"]:
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

%APPDATA% is used on Windows to locate application data folder

bdb.add_rec(**kwargs)
assert bdb.cur.execute.call_args[0][1] == exp_arg
finally:
bdb.cur = _cur
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This needs to be restored for correct cleanup

with open(exp_file.strpath, encoding="utf8", errors="surrogateescape") as f:
assert f.read()
f1 = NamedTemporaryFile(delete=False)
f1.close()
Copy link
Collaborator Author

@LeXofLeviafan LeXofLeviafan Dec 5, 2023

Choose a reason for hiding this comment

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

Similarly, temporary files need to be closed to be freely usable on Windows (i.e. to avoid access errors).

@LeXofLeviafan
Copy link
Collaborator Author

LeXofLeviafan commented Dec 5, 2023

…Incidentally, spawning a new thread for each tab doesn't actually seem to do anything in Windows (tried disabling it, and there were effectively no changes on any Windows version, including Windows 7… and changing Python version didn't affect much either).

And according to the docs, waiting for the user to finish working with the browser is only implemented in Unix for “non-remote” browsers (which I suspect means TUI browsers like Lynx):

For non-Unix platforms, or when a remote browser is available on Unix, the controlling process will not wait for the user to finish with the browser, but allow the remote browser to maintain its own windows on the display. If remote browsers are not available on Unix, the controlling process will launch a new browser and wait.

Do we still need this code, then?

@jarun
Copy link
Owner

jarun commented Dec 6, 2023

Do we still need this code, then?

If it isn't harming anything, let it be.

@jarun jarun merged commit ab03baf into jarun:master Dec 8, 2023
1 check passed
@jarun
Copy link
Owner

jarun commented Dec 8, 2023

Thank you!

@jarun
Copy link
Owner

jarun commented Jan 1, 2024

@LeXofLeviafan with this change I am hitting the following error on Ubuntu when I start buku:

$ ./buku -h
Traceback (most recent call last):
  File "/home/vaio/github/buku/./buku", line 6058, in <module>
    main()
  File "/home/vaio/github/buku/./buku", line 5284, in main
    colorama.just_fix_windows_console()  # noop on non-Windows systems
AttributeError: module 'colorama' has no attribute 'just_fix_windows_console'

@jarun
Copy link
Owner

jarun commented Jan 1, 2024

Fixed the error at commit 8668ef5. Please review.

@LeXofLeviafan
Copy link
Collaborator Author

LeXofLeviafan commented Jan 1, 2024

@jarun the code works on Linux. The issue is caused by the lack of a version requirement (>=0.4.6)

@jarun
Copy link
Owner

jarun commented Jan 1, 2024

Can you please raise a PR?

@LeXofLeviafan
Copy link
Collaborator Author

Can you please raise a PR?

#706

@github-actions github-actions bot locked and limited conversation to collaborators Feb 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Readline internal error
2 participants