tkinterweb 4.17.1__tar.gz → 4.17.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. {tkinterweb-4.17.1/tkinterweb.egg-info → tkinterweb-4.17.3}/PKG-INFO +1 -1
  2. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/setup.py +1 -1
  3. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/bindings.py +13 -11
  4. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/handlers.py +43 -40
  5. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/htmlwidgets.py +12 -6
  6. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/utilities.py +9 -8
  7. {tkinterweb-4.17.1 → tkinterweb-4.17.3/tkinterweb.egg-info}/PKG-INFO +1 -1
  8. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/LICENSE.md +0 -0
  9. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/MANIFEST.in +0 -0
  10. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/README.md +0 -0
  11. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/setup.cfg +0 -0
  12. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/__init__.py +0 -0
  13. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/dom.py +0 -0
  14. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/extensions.py +0 -0
  15. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/imageutils.py +0 -0
  16. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/js.py +0 -0
  17. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/resources/combobox-2.3.tm +0 -0
  18. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/resources/pkgIndex.tcl +0 -0
  19. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb/subwidgets.py +0 -0
  20. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb.egg-info/SOURCES.txt +0 -0
  21. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb.egg-info/dependency_links.txt +0 -0
  22. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb.egg-info/requires.txt +0 -0
  23. {tkinterweb-4.17.1 → tkinterweb-4.17.3}/tkinterweb.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tkinterweb
3
- Version: 4.17.1
3
+ Version: 4.17.3
4
4
  Summary: HTML/CSS viewer, editor, and app builder for Tkinter
5
5
  Home-page: https://github.com/Andereoo/TkinterWeb
6
6
  License: MIT
@@ -6,7 +6,7 @@ README = (HERE / "README.md").read_text()
6
6
 
7
7
  setup(
8
8
  name="tkinterweb",
9
- version="4.17.1",
9
+ version="4.17.3",
10
10
  python_requires=">=3.2",
11
11
  description="HTML/CSS viewer, editor, and app builder for Tkinter",
12
12
  long_description=README,
@@ -532,13 +532,13 @@ It is likely that not all dependencies are installed. Make sure Cairo is install
532
532
  self.queue_after = None
533
533
  self.queue = None
534
534
 
535
- def post_to_queue(self, callback):
535
+ def post_to_queue(self, callback, thread_safe=True):
536
536
  """Use this method to send a callback to TkinterWeb's thread-safety queue. The callback will be evaluated on the main thread.
537
537
  Use this when running Tkinter commands from within a thread.
538
538
  If the queue is not running (i.e. threading is disabled), the callback will be evaluated immediately.
539
539
 
540
540
  New in version 4.9."""
541
- if self.queue:
541
+ if thread_safe and self.queue:
542
542
  self.queue.put(callback)
543
543
  else:
544
544
  callback()
@@ -546,6 +546,7 @@ It is likely that not all dependencies are installed. Make sure Cairo is install
546
546
  def post_event(self, event, thread_safe=False):
547
547
  "Generate a virtual event."
548
548
  # NOTE: when thread_safe=True, this method is thread-safe
549
+ # Would you believe that?
549
550
  if not self.events_enabled:
550
551
  return
551
552
 
@@ -565,6 +566,7 @@ It is likely that not all dependencies are installed. Make sure Cairo is install
565
566
  def post_message(self, message, thread_safe=False):
566
567
  "Post a message."
567
568
  # NOTE: when thread_safe=True, this method is thread-safe
569
+ # Amazing stuff, eh?
568
570
  if not self.messages_enabled:
569
571
  return
570
572
 
@@ -722,20 +724,20 @@ It is likely that not all dependencies are installed. Make sure Cairo is install
722
724
  else:
723
725
  return utilities.cache_download(url, *args, insecure=self.insecure_https, cafile=self.ssl_cafile, headers=tuple(self.headers.items()), timeout=self.request_timeout)
724
726
 
725
- def _thread_check(self, callback, *args, **kwargs):
727
+ def _thread_check(self, callback, url, *args, **kwargs):
726
728
  if not self.downloads_have_occured:
727
729
  self.downloads_have_occured = True
728
730
 
729
- if not self.threading_enabled:
730
- callback(*args, **kwargs)
731
+ if not self.threading_enabled or url.startswith("file://"):
732
+ callback(url, *args, **kwargs)
731
733
  elif len(self.active_threads) >= self.maximum_thread_count:
732
- self.after(500, lambda callback=callback, args=args: self._thread_check(callback, *args, **kwargs))
734
+ self.after(500, lambda callback=callback, url=url, args=args: self._thread_check(callback, url, *args, **kwargs))
733
735
  else:
734
- thread = utilities.StoppableThread(target=callback, args=args, kwargs=kwargs)
736
+ thread = utilities.StoppableThread(target=callback, args=(url, *args,), kwargs=kwargs)
735
737
  thread.start()
736
738
 
737
739
  def _begin_download(self):
738
- # NOTE: this method is thread-safe and is designed to run in a thread
740
+ # NOTE: this runs in a thread
739
741
 
740
742
  thread = utilities.get_current_thread()
741
743
  self.active_threads.append(thread)
@@ -743,13 +745,13 @@ It is likely that not all dependencies are installed. Make sure Cairo is install
743
745
  return thread
744
746
 
745
747
  def _finish_download(self, thread):
746
- # NOTE: this method is thread-safe and is designed to run in a thread
748
+ # NOTE: this runs in a thread
747
749
 
748
750
  self.active_threads.remove(thread)
749
751
  if len(self.active_threads) == 0:
750
- self.post_to_queue(self._handle_load_finish)
752
+ self.post_to_queue(self._handle_load_finish, thread.is_subthread)
751
753
  else:
752
- self.post_to_queue(lambda: self._handle_load_finish(False))
754
+ self.post_to_queue(lambda: self._handle_load_finish(False), thread.is_subthread)
753
755
 
754
756
  def _finish_resource_load(self, message, url, resource, success):
755
757
  # NOTE: this must run in the main thread
@@ -471,7 +471,7 @@ class ScriptManager(utilities.BaseManager):
471
471
  attributes = dict(zip(attributes[::2], attributes[1::2])) # Make attributes a dict
472
472
 
473
473
  if "src" in attributes:
474
- self.html._thread_check(self.fetch_scripts, attributes, self.html.resolve_url(attributes["src"]))
474
+ self.html._thread_check(self.fetch_scripts, self.html.resolve_url(attributes["src"]), attributes)
475
475
  elif "defer" in attributes:
476
476
  self.pending_scripts.append((attributes, tag_contents))
477
477
  else:
@@ -479,27 +479,27 @@ class ScriptManager(utilities.BaseManager):
479
479
 
480
480
  def fetch_scripts(self, attributes, url=None, data=None):
481
481
  "Fetch and run scripts"
482
- # NOTE: this method is thread-safe and is designed to run in a thread
482
+ # NOTE: this runs in a thread
483
483
 
484
484
  thread = self.html._begin_download()
485
485
 
486
486
  if url and thread.isrunning():
487
- self.html.post_message(f"Fetching script from {utilities.shorten(url)}", True)
487
+ self.html.post_message(f"Fetching script from {utilities.shorten(url)}", thread.is_subthread)
488
488
  try:
489
489
  data = self.html.download_url(url)[1]
490
490
  except Exception as error:
491
491
  self.html.post_to_queue(lambda message=f"ERROR: could not load script {url}: {error}",
492
- url=url: self.html._finish_resource_load(message, url, "script", False))
492
+ url=url: self.html._finish_resource_load(message, url, "script", False), thread.is_subthread)
493
493
 
494
494
  if data and thread.isrunning():
495
495
  if "defer" in attributes:
496
496
  self.pending_scripts.append((attributes, data))
497
497
  else:
498
- self.html.post_to_queue(lambda attributes=attributes, data=data: self.html.on_script(attributes, data))
498
+ self.html.post_to_queue(lambda attributes=attributes, data=data: self.html.on_script(attributes, data), thread.is_subthread)
499
499
 
500
500
  if url:
501
501
  self.html.post_to_queue(lambda message=f"Successfully loaded {utilities.shorten(url)}",
502
- url=url: self.html._finish_resource_load(message, url, "script", True))
502
+ url=url: self.html._finish_resource_load(message, url, "script", True), thread.is_subthread)
503
503
 
504
504
  self.html._finish_download(thread)
505
505
 
@@ -520,7 +520,7 @@ class StyleManager(utilities.BaseManager):
520
520
 
521
521
  def _on_style(self, attributes, tag_contents):
522
522
  "Handle <style> elements."
523
- self.html._thread_check(self.fetch_styles, data=tag_contents)
523
+ self._finish_fetching_styles(data=tag_contents)
524
524
 
525
525
  def _on_link(self, node):
526
526
  "Handle <link> elements."
@@ -532,11 +532,9 @@ class StyleManager(utilities.BaseManager):
532
532
  except tk.TclError:
533
533
  return
534
534
 
535
- if (
536
- ("stylesheet" in rel)
537
- and ("all" in media or "screen" in media)
538
- ):
539
- self.html._thread_check(self.fetch_styles, node, url)
535
+ if (("stylesheet" in rel)
536
+ and ("all" in media or "screen" in media)):
537
+ self.html._thread_check(self.fetch_styles, url, node)
540
538
  # Onload is fired if and when the stylesheet is parsed
541
539
  elif "icon" in rel:
542
540
  self.html.icon = url
@@ -550,8 +548,7 @@ class StyleManager(utilities.BaseManager):
550
548
  try:
551
549
  new_url = self.html.resolve_url(new_url, parent_url)
552
550
  self.html.post_message(f"Loading stylesheet from {utilities.shorten(new_url)}")
553
-
554
- self.html._thread_check(self.fetch_styles, url=new_url)
551
+ self.html._thread_check(self.fetch_styles, new_url)
555
552
 
556
553
  except Exception as error:
557
554
  self.html.post_message(f"ERROR: could not load stylesheet {new_url}: {error}")
@@ -564,25 +561,25 @@ class StyleManager(utilities.BaseManager):
564
561
  newurl = f"url('{newurl}')"
565
562
  return newurl
566
563
 
567
- def fetch_styles(self, node=None, url=None, data=None):
564
+ def fetch_styles(self, url=None, node=None):
568
565
  "Fetch stylesheets and parse the CSS code they contain"
569
- # NOTE: this method is thread-safe and is designed to run in a thread
566
+ # NOTE: this runs in a thread
570
567
 
571
568
  thread = self.html._begin_download()
572
569
  if url and thread.isrunning():
573
- self.html.post_message(f"Fetching stylesheet from {utilities.shorten(url)}", True)
570
+ self.html.post_message(f"Fetching stylesheet from {utilities.shorten(url)}", thread.is_subthread)
574
571
  try:
575
572
  data = self.html.download_url(url)[1]
573
+ if data and thread.isrunning():
574
+ self.html.post_to_queue(lambda node=node, url=url, data=data: self._finish_fetching_styles(node, url, data), thread.is_subthread)
575
+
576
576
  except Exception as error:
577
577
  self.html.post_to_queue(lambda message=f"ERROR: could not load stylesheet {url}: {error}",
578
- url=url: self.html._finish_resource_load(message, url, "stylesheet", False))
579
-
580
- if data and thread.isrunning():
581
- self.html.post_to_queue(lambda node=node, url=url, data=data: self._finish_fetching_styles(node, url, data))
578
+ url=url: self.html._finish_resource_load(message, url, "stylesheet", False), thread.is_subthread)
582
579
 
583
580
  self.html._finish_download(thread)
584
581
 
585
- def _finish_fetching_styles(self, node, url, data):
582
+ def _finish_fetching_styles(self, node=None, url=None, data=None):
586
583
  # NOTE: this must run in the main thread
587
584
 
588
585
  self.html._style_count += 1
@@ -648,7 +645,7 @@ class ImageManager(utilities.BaseManager):
648
645
  self.bad_paths.add(url)
649
646
 
650
647
  if not self.html.ignore_invalid_images:
651
- image, data_is_image = self.check_images(utilities.BROKEN_IMAGE, name, url, "image/png")
648
+ image, data_is_image = self.check_images(utilities.BROKEN_IMAGE, name, url, "image/png", False)
652
649
  image = imageutils.data_to_image(image, name, "image/png", data_is_image)
653
650
 
654
651
  self.loaded_images.setdefault(name, set()).add(image)
@@ -695,29 +692,32 @@ class ImageManager(utilities.BaseManager):
695
692
 
696
693
  def fetch_images(self, url, name):
697
694
  "Fetch images and display them in the document."
698
- # NOTE: this method is thread-safe and is designed to run in a thread
695
+ # NOTE: this runs in a thread
699
696
 
700
697
  thread = self.html._begin_download()
701
698
  if thread.isrunning():
702
- self.html.post_message(f"Fetching image from {utilities.shorten(url)}", True)
699
+ self.html.post_message(f"Fetching image from {utilities.shorten(url)}", thread.is_subthread)
703
700
 
704
701
  if url == self.html.base_url:
705
- self.html.post_to_queue(lambda url=url, name=name, error="ERROR: image url not specified": self._on_image_error(url, name, error))
702
+ self.html.post_to_queue(lambda url=url, name=name, error="ERROR: image url not specified":
703
+ self._on_image_error(url, name, error), thread.is_subthread)
706
704
  else:
707
705
  try:
708
706
  url, data, filetype, code = self.html.download_url(url)
709
- data, data_is_image = self.check_images(data, name, url, filetype)
707
+ data, data_is_image = self.check_images(data, name, url, filetype, thread.is_subthread)
710
708
 
711
709
  if thread.isrunning():
712
- self.html.post_to_queue(lambda data=data, name=name, url=url, filetype=filetype, data_is_image=data_is_image: self.finish_fetching_images(data, name, url, filetype, data_is_image))
710
+ self.html.post_to_queue(lambda data=data, name=name, url=url, filetype=filetype, data_is_image=data_is_image:
711
+ self.finish_fetching_images(data, name, url, filetype, data_is_image), thread.is_subthread)
713
712
  except Exception as error:
714
- self.html.post_to_queue(lambda url=url, name=name, error=f"ERROR: could not load image {url}: {error}": self._on_image_error(url, name, error))
713
+ self.html.post_to_queue(lambda url=url, name=name, error=f"ERROR: could not load image {url}: {error}":
714
+ self._on_image_error(url, name, error), thread.is_subthread)
715
715
 
716
716
  self.html._finish_download(thread)
717
717
 
718
- def check_images(self, data, name, url, filetype):
718
+ def check_images(self, data, name, url, filetype, thread_safe):
719
719
  "Invert images if needed and convert SVG images to PNGs."
720
- # NOTE: this method is thread-safe and is designed to run in a thread
720
+ # NOTE: this runs in a thread
721
721
 
722
722
  data_is_image = False
723
723
  if "svg" in filetype:
@@ -732,7 +732,7 @@ class ImageManager(utilities.BaseManager):
732
732
  data_is_image = True
733
733
  except (ImportError, ModuleNotFoundError,):
734
734
  error = f"ERROR: could not invert the image {url}: PIL and PIL.ImageTk must be installed."
735
- self.html.post_to_queue(lambda url=url, name=name, error=error: self._on_image_error(url, name, error))
735
+ self.html.post_to_queue(lambda url=url, name=name, error=error: self._on_image_error(url, name, error), thread_safe)
736
736
 
737
737
  return data, data_is_image
738
738
 
@@ -887,7 +887,7 @@ class ObjectManager(utilities.BaseManager):
887
887
  return
888
888
 
889
889
  self.html.post_message(f"Creating object from {utilities.shorten(data)}")
890
- self.html._thread_check(self.fetch_objects, node, data)
890
+ self.html._thread_check(self.fetch_objects, data, node)
891
891
 
892
892
  def _on_object_value_change(self, node, attribute, value):
893
893
  if attribute == "data":
@@ -898,10 +898,11 @@ class ObjectManager(utilities.BaseManager):
898
898
  # Force reset because it might contain widgets that are added internally
899
899
  self.html.widget_manager.map_node(node, True)
900
900
 
901
- def fetch_objects(self, node, url):
902
- # NOTE: this method is thread-safe and is designed to run in a thread
901
+ def fetch_objects(self, url, node):
902
+ # NOTE: this runs in a thread
903
903
 
904
904
  thread = self.html._begin_download()
905
+
905
906
  if thread.isrunning():
906
907
  try:
907
908
  url, data, filetype, code = self.html.download_url(url)
@@ -909,10 +910,12 @@ class ObjectManager(utilities.BaseManager):
909
910
  if data and thread.isrunning():
910
911
  if filetype.startswith("image"):
911
912
  name = self.html.image_manager.allocate_image_name()
912
- data, data_is_image = self.html.image_manager.check_images(data, name, url, filetype)
913
- self.html.post_to_queue(lambda node=node, data=data, name=name, url=url, filetype=filetype, data_is_image=data_is_image: self._finish_fetching_image_objects(node, data, name, url, filetype, data_is_image))
913
+ data, data_is_image = self.html.image_manager.check_images(data, name, url, filetype, thread.is_subthread)
914
+ self.html.post_to_queue(lambda node=node, data=data, name=name, url=url, filetype=filetype, data_is_image=data_is_image:
915
+ self._finish_fetching_image_objects(node, data, name, url, filetype, data_is_image), thread.is_subthread)
914
916
  elif filetype == "text/html":
915
- self.html.post_to_queue(lambda node=node, data=data, name=name, url=url, filetype=filetype: self._finish_fetching_HTML_objects(node, data, name, url, filetype))
917
+ self.html.post_to_queue(lambda node=node, data=data, url=url, filetype=filetype:
918
+ self._finish_fetching_HTML_objects(node, data, url, filetype), thread.is_subthread)
916
919
 
917
920
  except Exception as error:
918
921
  self.html.post_message(f"ERROR: could not load object element with data {url}: {error}", True)
@@ -920,9 +923,9 @@ class ObjectManager(utilities.BaseManager):
920
923
  self.html._finish_download(thread)
921
924
 
922
925
  def _finish_fetching_image_objects(self, node, data, name, url, filetype, data_is_image):
923
- # NOTE: this must run in the main thread
926
+ # NOTE: this must run in the main thread
924
927
 
925
- image = self.html.image_manager.finish_fetching_images(None, data, name, filetype, url, data_is_image)
928
+ image = self.html.image_manager.finish_fetching_images(data, name, filetype, url, data_is_image)
926
929
  self.html.override_node_properties(node, "-tkhtml-replacement-image", f"url({image})")
927
930
  self.html.event_manager.post_element_event(node, "onload", None, utilities.ELEMENT_LOADED_EVENT)
928
931
 
@@ -437,7 +437,7 @@ class HtmlFrame(Frame):
437
437
  file_url = "file://" + str(file_url)
438
438
  self._current_url = file_url
439
439
  self._html.post_event(utilities.URL_CHANGED_EVENT)
440
- self._continue_loading(file_url, decode=decode, force=force)
440
+ self.load_url(file_url, decode, force)
441
441
 
442
442
  def load_website(self, website_url, decode=None, force=False):
443
443
  """Convenience method to load a website.
@@ -482,7 +482,8 @@ class HtmlFrame(Frame):
482
482
 
483
483
  if self._thread_in_progress:
484
484
  self._thread_in_progress.stop()
485
- if self._html.threading_enabled:
485
+
486
+ if self._html.threading_enabled and not url.startswith("file://"):
486
487
  thread = utilities.StoppableThread(target=self._continue_loading, args=(
487
488
  url,), kwargs={"decode": decode, "force": force, "thread_safe": True})
488
489
  self._thread_in_progress = thread
@@ -1131,6 +1132,9 @@ class HtmlFrame(Frame):
1131
1132
 
1132
1133
  if self.unshrink:
1133
1134
  if event.x and self._prev_configure != (event.width, event.x):
1135
+ # if not self._html.using_tkhtml30:
1136
+ # self._html.configure(textwrap=False)
1137
+ # self.after(10, lambda: self._html.configure(textwrap=True))
1134
1138
  self.after_idle(lambda: self._html.configure(
1135
1139
  width=self.winfo_screenwidth(),
1136
1140
  height=event.height)
@@ -1183,7 +1187,7 @@ class HtmlFrame(Frame):
1183
1187
 
1184
1188
  def _continue_loading(self, url, data="", method="GET", decode=None, force=False, thread_safe=False):
1185
1189
  "Finish loading urls and handle URI fragments."
1186
- # NOTE: this method is thread-safe and is designed to run in a thread
1190
+ # NOTE: this runs in a thread
1187
1191
 
1188
1192
  code = 404
1189
1193
  self._current_url = url
@@ -1219,6 +1223,8 @@ class HtmlFrame(Frame):
1219
1223
  url = url.replace("view-source:", "")
1220
1224
  parsed = urlparse(url)
1221
1225
 
1226
+ thread = utilities.get_current_thread()
1227
+
1222
1228
  location = parsed.netloc if parsed.netloc else parsed.path
1223
1229
  self._html.post_message(f"Connecting to {location}", True)
1224
1230
  if self._html.insecure_https: self._html.post_message("WARNING: Using insecure HTTPS session", True)
@@ -1226,7 +1232,7 @@ class HtmlFrame(Frame):
1226
1232
  newurl, data, filetype, code = self._html.download_url(url, data, method, decode)
1227
1233
  self._html.post_message(f"Successfully connected to {location}", True)
1228
1234
 
1229
- if utilities.get_current_thread().isrunning():
1235
+ if thread.isrunning():
1230
1236
  if view_source:
1231
1237
  newurl = "view-source:"+newurl
1232
1238
  if self._current_url != newurl:
@@ -1246,7 +1252,7 @@ class HtmlFrame(Frame):
1246
1252
  elif "image" in filetype:
1247
1253
  name = self._html.image_manager.allocate_image_name()
1248
1254
  if name:
1249
- data, data_is_image = self._html.image_manager.check_images(data, name, url, filetype)
1255
+ data, data_is_image = self._html.image_manager.check_images(data, name, url, filetype, thread.is_subthread)
1250
1256
  self._html.post_to_queue(lambda data=data, name=name, url=url, filetype=filetype, data_is_image=data_is_image: self._finish_loading_image(data, name, url, filetype, data_is_image))
1251
1257
  else:
1252
1258
  self.load_html(self._get_about_page("about:image", name), newurl, _thread_safe=thread_safe)
@@ -1271,7 +1277,7 @@ class HtmlFrame(Frame):
1271
1277
  if self._current_url != url:
1272
1278
  self._html.post_event(utilities.URL_CHANGED_EVENT)
1273
1279
  text = self._get_about_page("about:image", name)
1274
- self._html.image_manager.finish_fetching_images(None, data, name, url, filetype, data_is_image)
1280
+ self._html.image_manager.finish_fetching_images(data, name, url, filetype, data_is_image)
1275
1281
  self.load_html(text, url)
1276
1282
 
1277
1283
  def _finish_loading_nothing(self):
@@ -31,7 +31,7 @@ __title__ = "TkinterWeb"
31
31
  __author__ = "Andrew Clarke"
32
32
  __copyright__ = "(c) 2021-2025 Andrew Clarke"
33
33
  __license__ = "MIT"
34
- __version__ = "4.17.1"
34
+ __version__ = "4.17.3"
35
35
 
36
36
 
37
37
  ROOT_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), "resources")
@@ -686,6 +686,8 @@ class StoppableThread(threading.Thread):
686
686
  self.daemon = True
687
687
  self.running = True
688
688
 
689
+ self.is_subthread = True
690
+
689
691
  def stop(self):
690
692
  self.running = False
691
693
 
@@ -697,6 +699,9 @@ class PlaceholderThread:
697
699
  """Fake StoppableThread. The only purpose of this is to provide fake methods that mirror the StoppableThread class.
698
700
  This means that if a download is running in the MainThread, the stop flags can still be set without raising errors, though they won't do anything."""
699
701
 
702
+ def __init__(self, *args, **kwargs):
703
+ self.is_subthread = False
704
+
700
705
  def stop(self):
701
706
  return
702
707
 
@@ -855,14 +860,11 @@ def download(url, data=None, method="GET", decode=None, insecure=False, cafile=N
855
860
  parsed = urlparse(url)
856
861
  url = urlunparse(parsed._replace(query=""))
857
862
 
858
- thread = get_current_thread()
859
863
  url = url.replace(" ", "%20")
860
864
  if data and (method == "POST"):
861
865
  req = Request(url, data, headers=dict(headers))
862
866
  else:
863
867
  req = Request(url, headers=dict(headers))
864
- if not thread.isrunning():
865
- return None, url, "", ""
866
868
 
867
869
  with urlopen(req, context=context, timeout=timeout) as res:
868
870
  data = res.read()
@@ -893,10 +895,8 @@ def download(url, data=None, method="GET", decode=None, insecure=False, cafile=N
893
895
  data = data.decode(decode, errors="ignore")
894
896
  else:
895
897
  data = data.decode(errors="ignore")
896
- if not thread.isrunning():
897
- return url, None, "", code
898
- else:
899
- return url, data, filetype, code
898
+
899
+ return url, data, filetype, code
900
900
 
901
901
 
902
902
  @lru_cache()
@@ -915,6 +915,7 @@ def shorten(string):
915
915
  def get_current_thread():
916
916
  "Return the currently running thread"
917
917
  thread = threading.current_thread()
918
+ # Py 3.4+: Use is threading.main_thread()
918
919
  if thread.name == "MainThread":
919
920
  thread = PlaceholderThread()
920
921
  return thread
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tkinterweb
3
- Version: 4.17.1
3
+ Version: 4.17.3
4
4
  Summary: HTML/CSS viewer, editor, and app builder for Tkinter
5
5
  Home-page: https://github.com/Andereoo/TkinterWeb
6
6
  License: MIT
File without changes
File without changes
File without changes
File without changes