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

Use typeguard during tests and in osc-wrapper.py #1424

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ jobs:
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'
sudo apt-get -y update
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
sudo pip3 install typeguard

- name: "Checkout sources"
uses: actions/checkout@v3
Expand Down
10 changes: 10 additions & 0 deletions contrib/osc.spec
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@
%bcond_with fdupes
%endif

# use typeguard during build on distros where typeguard is available
%if (0%{?suse_version} > 1500 || 0%{?fedora} >= 37)
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't have to care about Fedora 36 and older

Suggested change
%if (0%{?suse_version} > 1500 || 0%{?fedora} >= 37)
%if (0%{?suse_version} > 1500 || 0%{?fedora})

%bcond_without typeguard
%else
%bcond_with typeguard
%endif

%define argparse_manpage_pkg argparse-manpage
%define obs_build_pkg obs-build
%define ssh_add_pkg openssh-clients
Expand Down Expand Up @@ -69,6 +76,9 @@ BuildRequires: %{use_python_pkg}-cryptography
BuildRequires: %{use_python_pkg}-devel >= 3.6
BuildRequires: %{use_python_pkg}-rpm
BuildRequires: %{use_python_pkg}-setuptools
%if %{with typeguard}
BuildRequires: %{use_python_pkg}-typeguard
%endif
BuildRequires: %{use_python_pkg}-urllib3
BuildRequires: diffstat
%if %{with fdupes}
Expand Down
23 changes: 23 additions & 0 deletions osc-wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,29 @@
This wrapper allows osc to be called from the source directory during development.
"""


import os


USE_TYPEGUARD = os.environ.get("OSC_TYPEGUARD", "1").lower() in ("1", "true", "on")

if USE_TYPEGUARD:
try:
from typeguard import install_import_hook
except ImportError:
install_import_hook = None

if install_import_hook is None:
try:
from typeguard.importhook import install_import_hook
except ImportError:
install_import_hook = None

if install_import_hook:
# install typeguard import hook only if available
install_import_hook("osc")
Fixed Show fixed Hide fixed


import osc.babysitter

osc.babysitter.main()
28 changes: 14 additions & 14 deletions osc/commandline.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,10 +594,10 @@ def pop_args(
args,
arg1_name: str = None,
arg1_is_optional: bool = False,
arg1_default: str = None,
arg1_default: Optional[str] = None,
arg2_name: str = None,
arg2_is_optional: bool = False,
arg2_default: str = None,
arg2_default: Optional[str] = None,
):
"""
Pop 2 arguments from `args`.
Expand Down Expand Up @@ -669,9 +669,9 @@ def pop_args(
def pop_project_package_from_args(
args: List[str],
project_is_optional: bool = False,
default_project: str = None,
default_project: Optional[str] = None,
package_is_optional: bool = False,
default_package: str = None,
default_package: Optional[str] = None,
):
"""
Pop project and package from given `args`.
Expand Down Expand Up @@ -740,9 +740,9 @@ def pop_project_package_from_args(
def pop_repository_arch_from_args(
args: List[str],
repository_is_optional: bool = False,
default_repository: str = None,
default_repository: Optional[str] = None,
arch_is_optional: bool = False,
default_arch: str = None,
default_arch: Optional[str] = None,
):
"""
Pop repository and arch from given `args`.
Expand Down Expand Up @@ -779,13 +779,13 @@ def pop_repository_arch_from_args(
def pop_project_package_repository_arch_from_args(
args: List[str],
project_is_optional: bool = False,
default_project: str = None,
default_project: Optional[str] = None,
package_is_optional: bool = False,
default_package: str = None,
default_package: Optional[str] = None,
repository_is_optional: bool = False,
default_repository: str = None,
default_repository: Optional[str] = None,
arch_is_optional: bool = False,
default_arch: str = None,
default_arch: Optional[str] = None,
):
"""
Pop project, package, repository and arch from given `args`.
Expand Down Expand Up @@ -865,13 +865,13 @@ def pop_project_package_repository_arch_from_args(
def pop_project_package_targetproject_targetpackage_from_args(
args: List[str],
project_is_optional: bool = False,
default_project: str = None,
default_project: Optional[str] = None,
package_is_optional: bool = False,
default_package: str = None,
default_package: Optional[str] = None,
target_project_is_optional: bool = False,
default_target_project: str = None,
default_target_project: Optional[str] = None,
target_package_is_optional: bool = False,
default_target_package: str = None,
default_target_package: Optional[str] = None,
):
"""
Pop project, package, target project and target package from given `args`.
Expand Down
30 changes: 15 additions & 15 deletions osc/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2319,7 +2319,7 @@ def get_request_collection(
package=None,
states=None,
review_states=None,
types: List[str] = None,
types: Optional[List[str]] = None,
ids=None,
withfullhistory=False
):
Expand Down Expand Up @@ -2862,20 +2862,20 @@ def get_source_file_diff(dir, filename, rev, oldfilename=None, olddir=None, orig

def server_diff(
apiurl: str,
old_project: str,
old_package: str,
old_revision: str,
old_project: Optional[str],
old_package: Optional[str],
old_revision: Optional[str],
new_project: str,
new_package: str,
new_revision: str,
new_revision: Optional[str],
unified=False,
missingok=False,
meta=False,
expand=True,
onlyissues=False,
full=True,
xml=False,
files: list = None,
files: Optional[list] = None,
):
query: Dict[str, Union[str, int]] = {"cmd": "diff"}
if expand:
Expand Down Expand Up @@ -2928,19 +2928,19 @@ def server_diff(

def server_diff_noex(
apiurl: str,
old_project: str,
old_package: str,
old_revision: str,
old_project: Optional[str],
old_package: Optional[str],
old_revision: Optional[str],
new_project: str,
new_package: str,
new_revision: str,
new_revision: Optional[str],
unified=False,
missingok=False,
meta=False,
expand=True,
onlyissues=False,
xml=False,
files: list = None,
files: Optional[list] = None,
):
try:
return server_diff(apiurl,
Expand Down Expand Up @@ -3087,7 +3087,7 @@ def checkout_package(
pathname=None,
prj_obj=None,
expand_link=False,
prj_dir: Path=None,
prj_dir: Optional[Path] = None,
server_service_files=None,
service_files=None,
progress_obj=None,
Expand Down Expand Up @@ -3792,7 +3792,7 @@ def copy_pac(
return 'Done.'


def lock(apiurl: str, project: str, package: str, msg: str = None):
def lock(apiurl: str, project: str, package: str, msg: Optional[str] = None):
url_path = ["source", project]
if package:
url_path += [package]
Expand Down Expand Up @@ -5097,7 +5097,7 @@ def owner(
return res


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


def _set_link_rev(apiurl: str, project: str, package: str, root, revision="", expand=False, setvrev: str=None):
def _set_link_rev(apiurl: str, project: str, package: str, root, revision="", expand=False, setvrev: Optional[str] = None):
"""
Updates the rev attribute of the _link xml. If revision is set to None
the rev and vrev attributes are removed from the _link xml.
Expand Down
2 changes: 1 addition & 1 deletion osc/meter.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def end(self):
self.bar.finish()


class NoPBTextMeter:
class NoPBTextMeter(TextMeterBase):
def start(self, basename: str, size: Optional[int] = None):
pass

Expand Down
6 changes: 4 additions & 2 deletions osc/output/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import subprocess
import sys
import tempfile
from typing import BinaryIO
from typing import Dict
from typing import Generator
from typing import List
from typing import Optional
from typing import TextIO
Expand Down Expand Up @@ -137,7 +139,7 @@ def safe_print(*args, **kwargs):
print(*args, **kwargs)


def safe_write(file: TextIO, text: Union[str, bytes], *, add_newline: bool = False):
def safe_write(file: Union[BinaryIO, TextIO], text: Union[str, bytes], *, add_newline: bool = False):
"""
Run sanitize_text() on ``text`` and write it to ``file``.

Expand Down Expand Up @@ -211,7 +213,7 @@ def run_pager(message: Union[bytes, str], tmp_suffix: str = ""):
run_external(*cmd, env=env)


def pipe_to_pager(lines: Union[List[bytes], List[str]], *, add_newlines=False):
def pipe_to_pager(lines: Union[List[bytes], List[str], Generator[bytes, None, None], Generator[str, None, None]], *, add_newlines=False):
"""
Pipe ``lines`` to the pager.
If running in a non-interactive terminal, print the data instead.
Expand Down
19 changes: 18 additions & 1 deletion osc/util/safewriter.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
import io

# be careful when debugging this code:
# don't add print statements when setting sys.stdout = SafeWriter(sys.stdout)...
class SafeWriter:
class SafeWriter(io.TextIOBase):
"""
Safely write an (unicode) str. In case of an "UnicodeEncodeError" the
the str is encoded with the "encoding" encoding.
All getattr, setattr calls are passed through to the "writer" instance.
"""

def __init__(self, writer, encoding='unicode_escape'):
super().__init__()
self._writer = writer
self._encoding = encoding

# TextIOBase requires overriding the following stub methods: detach, read, readline, and write

def detach(self, *args, **kwargs):
return self._writer.detach(*args, **kwargs)

def read(self, *args, **kwargs):
return self._writer.read(args, **kwargs)

def readline(self, *args, **kwargs):
return self._writer.readline(args, **kwargs)

def write(self, s):
try:
self._writer.write(s)
except UnicodeEncodeError as e:
self._writer.write(s.encode(self._encoding))

def fileno(self, *args, **kwargs):
return self._writer.fileno(*args, **kwargs)

def __getattr__(self, name):
return getattr(self._writer, name)

Expand Down
14 changes: 14 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
try:
from typeguard import install_import_hook
except ImportError:
Fixed Show fixed Hide fixed
install_import_hook = None

if not install_import_hook:
try:
from typeguard.importhook import install_import_hook
except ImportError:
install_import_hook = None

if install_import_hook:
# install typeguard import hook only if available
install_import_hook("osc")
Loading