Skip to content

Commit 11d256c

Browse files
committed
Enable typeguard during build time and tests, fix issues found
1 parent 98a9b83 commit 11d256c

9 files changed

Lines changed: 100 additions & 33 deletions

File tree

.github/workflows/tests.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ jobs:
106106
sudo sh -c '. /etc/os-release; echo "deb [trusted=yes] http://download.opensuse.org/repositories/openSUSE:Tools/xUbuntu_${VERSION_ID} ./" > /etc/apt/sources.list.d/openSUSE-Tools.list'
107107
sudo apt-get -y update
108108
sudo apt-get -y --no-install-recommends install python3-behave diffstat diffutils python3 python3-cryptography python3-pip python3-rpm python3-setuptools python3-urllib3 obs-build obs-service-set-version
109+
sudo pip3 install typeguard
109110
110111
- name: "Checkout sources"
111112
uses: actions/checkout@v3

contrib/osc.spec

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030
%bcond_with fdupes
3131
%endif
3232

33+
# use typeguard during build on distros where typeguard is available
34+
%if (0%{?suse_version} > 1500 || 0%{?fedora} >= 37)
35+
%bcond_without typeguard
36+
%else
37+
%bcond_with typeguard
38+
%endif
39+
3340
%define argparse_manpage_pkg argparse-manpage
3441
%define obs_build_pkg obs-build
3542
%define ssh_add_pkg openssh-clients
@@ -69,6 +76,9 @@ BuildRequires: %{use_python_pkg}-cryptography
6976
BuildRequires: %{use_python_pkg}-devel >= 3.6
7077
BuildRequires: %{use_python_pkg}-rpm
7178
BuildRequires: %{use_python_pkg}-setuptools
79+
%if %{with typeguard}
80+
BuildRequires: %{use_python_pkg}-typeguard
81+
%endif
7282
BuildRequires: %{use_python_pkg}-urllib3
7383
BuildRequires: diffstat
7484
%if %{with fdupes}

osc-wrapper.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,29 @@
44
This wrapper allows osc to be called from the source directory during development.
55
"""
66

7+
8+
import os
9+
10+
11+
USE_TYPEGUARD = os.environ.get("OSC_TYPEGUARD", "1").lower() in ("1", "true", "on")
12+
13+
if USE_TYPEGUARD:
14+
try:
15+
from typeguard import install_import_hook
16+
except ImportError:
17+
install_import_hook = None
18+
19+
if install_import_hook is None:
20+
try:
21+
from typeguard.importhook import install_import_hook
22+
except ImportError:
23+
install_import_hook = None
24+
25+
if install_import_hook and 0:
26+
# install typeguard import hook only if available
27+
install_import_hook("osc")
28+
29+
730
import osc.babysitter
831

932
osc.babysitter.main()

osc/commandline.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -594,10 +594,10 @@ def pop_args(
594594
args,
595595
arg1_name: str = None,
596596
arg1_is_optional: bool = False,
597-
arg1_default: str = None,
597+
arg1_default: Optional[str] = None,
598598
arg2_name: str = None,
599599
arg2_is_optional: bool = False,
600-
arg2_default: str = None,
600+
arg2_default: Optional[str] = None,
601601
):
602602
"""
603603
Pop 2 arguments from `args`.
@@ -669,9 +669,9 @@ def pop_args(
669669
def pop_project_package_from_args(
670670
args: List[str],
671671
project_is_optional: bool = False,
672-
default_project: str = None,
672+
default_project: Optional[str] = None,
673673
package_is_optional: bool = False,
674-
default_package: str = None,
674+
default_package: Optional[str] = None,
675675
):
676676
"""
677677
Pop project and package from given `args`.
@@ -740,9 +740,9 @@ def pop_project_package_from_args(
740740
def pop_repository_arch_from_args(
741741
args: List[str],
742742
repository_is_optional: bool = False,
743-
default_repository: str = None,
743+
default_repository: Optional[str] = None,
744744
arch_is_optional: bool = False,
745-
default_arch: str = None,
745+
default_arch: Optional[str] = None,
746746
):
747747
"""
748748
Pop repository and arch from given `args`.
@@ -779,13 +779,13 @@ def pop_repository_arch_from_args(
779779
def pop_project_package_repository_arch_from_args(
780780
args: List[str],
781781
project_is_optional: bool = False,
782-
default_project: str = None,
782+
default_project: Optional[str] = None,
783783
package_is_optional: bool = False,
784-
default_package: str = None,
784+
default_package: Optional[str] = None,
785785
repository_is_optional: bool = False,
786-
default_repository: str = None,
786+
default_repository: Optional[str] = None,
787787
arch_is_optional: bool = False,
788-
default_arch: str = None,
788+
default_arch: Optional[str] = None,
789789
):
790790
"""
791791
Pop project, package, repository and arch from given `args`.
@@ -865,13 +865,13 @@ def pop_project_package_repository_arch_from_args(
865865
def pop_project_package_targetproject_targetpackage_from_args(
866866
args: List[str],
867867
project_is_optional: bool = False,
868-
default_project: str = None,
868+
default_project: Optional[str] = None,
869869
package_is_optional: bool = False,
870-
default_package: str = None,
870+
default_package: Optional[str] = None,
871871
target_project_is_optional: bool = False,
872-
default_target_project: str = None,
872+
default_target_project: Optional[str] = None,
873873
target_package_is_optional: bool = False,
874-
default_target_package: str = None,
874+
default_target_package: Optional[str] = None,
875875
):
876876
"""
877877
Pop project, package, target project and target package from given `args`.

osc/core.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,7 +2319,7 @@ def get_request_collection(
23192319
package=None,
23202320
states=None,
23212321
review_states=None,
2322-
types: List[str] = None,
2322+
types: Optional[List[str]] = None,
23232323
ids=None,
23242324
withfullhistory=False
23252325
):
@@ -2862,20 +2862,20 @@ def get_source_file_diff(dir, filename, rev, oldfilename=None, olddir=None, orig
28622862

28632863
def server_diff(
28642864
apiurl: str,
2865-
old_project: str,
2866-
old_package: str,
2867-
old_revision: str,
2865+
old_project: Optional[str],
2866+
old_package: Optional[str],
2867+
old_revision: Optional[str],
28682868
new_project: str,
28692869
new_package: str,
2870-
new_revision: str,
2870+
new_revision: Optional[str],
28712871
unified=False,
28722872
missingok=False,
28732873
meta=False,
28742874
expand=True,
28752875
onlyissues=False,
28762876
full=True,
28772877
xml=False,
2878-
files: list = None,
2878+
files: Optional[list] = None,
28792879
):
28802880
query: Dict[str, Union[str, int]] = {"cmd": "diff"}
28812881
if expand:
@@ -2928,19 +2928,19 @@ def server_diff(
29282928

29292929
def server_diff_noex(
29302930
apiurl: str,
2931-
old_project: str,
2932-
old_package: str,
2933-
old_revision: str,
2931+
old_project: Optional[str],
2932+
old_package: Optional[str],
2933+
old_revision: Optional[str],
29342934
new_project: str,
29352935
new_package: str,
2936-
new_revision: str,
2936+
new_revision: Optional[str],
29372937
unified=False,
29382938
missingok=False,
29392939
meta=False,
29402940
expand=True,
29412941
onlyissues=False,
29422942
xml=False,
2943-
files: list = None,
2943+
files: Optional[list] = None,
29442944
):
29452945
try:
29462946
return server_diff(apiurl,
@@ -3087,7 +3087,7 @@ def checkout_package(
30873087
pathname=None,
30883088
prj_obj=None,
30893089
expand_link=False,
3090-
prj_dir: Path=None,
3090+
prj_dir: Optional[Path] = None,
30913091
server_service_files=None,
30923092
service_files=None,
30933093
progress_obj=None,
@@ -3792,7 +3792,7 @@ def copy_pac(
37923792
return 'Done.'
37933793

37943794

3795-
def lock(apiurl: str, project: str, package: str, msg: str = None):
3795+
def lock(apiurl: str, project: str, package: str, msg: Optional[str] = None):
37963796
url_path = ["source", project]
37973797
if package:
37983798
url_path += [package]
@@ -5097,7 +5097,7 @@ def owner(
50975097
return res
50985098

50995099

5100-
def set_link_rev(apiurl: str, project: str, package: str, revision="", expand=False, msg: str=None, vrev: str=None):
5100+
def set_link_rev(apiurl: str, project: str, package: str, revision="", expand=False, msg: Optional[str] = None, vrev: Optional[str] = None):
51015101
url = makeurl(apiurl, ["source", project, package, "_link"])
51025102
try:
51035103
f = http_GET(url)
@@ -5118,7 +5118,7 @@ def set_link_rev(apiurl: str, project: str, package: str, revision="", expand=Fa
51185118
return revision
51195119

51205120

5121-
def _set_link_rev(apiurl: str, project: str, package: str, root, revision="", expand=False, setvrev: str=None):
5121+
def _set_link_rev(apiurl: str, project: str, package: str, root, revision="", expand=False, setvrev: Optional[str] = None):
51225122
"""
51235123
Updates the rev attribute of the _link xml. If revision is set to None
51245124
the rev and vrev attributes are removed from the _link xml.

osc/meter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def end(self):
6060
self.bar.finish()
6161

6262

63-
class NoPBTextMeter:
63+
class NoPBTextMeter(TextMeterBase):
6464
def start(self, basename: str, size: Optional[int] = None):
6565
pass
6666

osc/output/output.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import subprocess
66
import sys
77
import tempfile
8+
from typing import BinaryIO
89
from typing import Dict
10+
from typing import Generator
911
from typing import List
1012
from typing import Optional
1113
from typing import TextIO
@@ -137,7 +139,7 @@ def safe_print(*args, **kwargs):
137139
print(*args, **kwargs)
138140

139141

140-
def safe_write(file: TextIO, text: Union[str, bytes], *, add_newline: bool = False):
142+
def safe_write(file: Union[BinaryIO, TextIO], text: Union[str, bytes], *, add_newline: bool = False):
141143
"""
142144
Run sanitize_text() on ``text`` and write it to ``file``.
143145
@@ -211,7 +213,7 @@ def run_pager(message: Union[bytes, str], tmp_suffix: str = ""):
211213
run_external(*cmd, env=env)
212214

213215

214-
def pipe_to_pager(lines: Union[List[bytes], List[str]], *, add_newlines=False):
216+
def pipe_to_pager(lines: Union[List[bytes], List[str], Generator[bytes, None, None], Generator[str, None, None]], *, add_newlines=False):
215217
"""
216218
Pipe ``lines`` to the pager.
217219
If running in a non-interactive terminal, print the data instead.

osc/util/safewriter.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,39 @@
1+
import io
2+
13
# be careful when debugging this code:
24
# don't add print statements when setting sys.stdout = SafeWriter(sys.stdout)...
3-
class SafeWriter:
5+
class SafeWriter(io.TextIOBase):
46
"""
57
Safely write an (unicode) str. In case of an "UnicodeEncodeError" the
68
the str is encoded with the "encoding" encoding.
79
All getattr, setattr calls are passed through to the "writer" instance.
810
"""
911

1012
def __init__(self, writer, encoding='unicode_escape'):
13+
super().__init__()
1114
self._writer = writer
1215
self._encoding = encoding
1316

17+
# TextIOBase requires overriding the following stub methods: detach, read, readline, and write
18+
19+
def detach(self, *args, **kwargs):
20+
return self._writer.detach(*args, **kwargs)
21+
22+
def read(self, *args, **kwargs):
23+
return self._writer.read(args, **kwargs)
24+
25+
def readline(self, *args, **kwargs):
26+
return self._writer.readline(args, **kwargs)
27+
1428
def write(self, s):
1529
try:
1630
self._writer.write(s)
1731
except UnicodeEncodeError as e:
1832
self._writer.write(s.encode(self._encoding))
1933

34+
def fileno(self, *args, **kwargs):
35+
return self._writer.fileno(*args, **kwargs)
36+
2037
def __getattr__(self, name):
2138
return getattr(self._writer, name)
2239

tests/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
try:
2+
from typeguard import install_import_hook
3+
except ImportError:
4+
install_import_hook = None
5+
6+
if not install_import_hook:
7+
try:
8+
from typeguard.importhook import install_import_hook
9+
except ImportError:
10+
install_import_hook = None
11+
12+
if install_import_hook:
13+
# install typeguard import hook only if available
14+
install_import_hook("osc")

0 commit comments

Comments
 (0)