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

speed up import time #5770

Merged
merged 1 commit into from
Oct 17, 2023
Merged
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
2 changes: 1 addition & 1 deletion cylc/flow/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
import cylc.flow.flags
from cylc.flow.graph_parser import GraphParser
from cylc.flow.listify import listify
from cylc.flow.option_parsers import verbosity_to_env
from cylc.flow.log_level import verbosity_to_env
from cylc.flow.graphnode import GraphNodeParser
from cylc.flow.param_expand import NameExpander
from cylc.flow.parsec.exceptions import ItemNotFoundError
Expand Down
7 changes: 5 additions & 2 deletions cylc/flow/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,14 @@
Tuple,
Type,
Union,
TYPE_CHECKING,
)

from cylc.flow.subprocctx import SubFuncContext
from cylc.flow.util import format_cmd

if TYPE_CHECKING:
from cylc.flow.subprocctx import SubFuncContext


class CylcError(Exception):
"""Generic exception for Cylc errors.
Expand Down Expand Up @@ -198,7 +201,7 @@ def __init__(
message: str,
platform_name: str,
*,
ctx: Optional[SubFuncContext] = None,
ctx: 'Optional[SubFuncContext]' = None,
cmd: Optional[Union[str, Iterable]] = None,
ret_code: Optional[int] = None,
out: Optional[str] = None,
Expand Down
7 changes: 5 additions & 2 deletions cylc/flow/flow_mgr.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@

"""Manage flow counter and flow metadata."""

from typing import Dict, Set, Optional
from typing import Dict, Set, Optional, TYPE_CHECKING
import datetime

from cylc.flow import LOG
from cylc.flow.workflow_db_mgr import WorkflowDatabaseManager


if TYPE_CHECKING:
from cylc.flow.workflow_db_mgr import WorkflowDatabaseManager


FlowNums = Set[int]
Expand Down
11 changes: 6 additions & 5 deletions cylc/flow/id_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,6 @@
upgrade_legacy_ids,
)
from cylc.flow.pathutil import EXPLICIT_RELATIVE_PATH_REGEX
from cylc.flow.network.scan import (
filter_name,
is_active,
scan,
)
from cylc.flow.workflow_files import (
check_flow_file,
detect_both_flow_and_suite,
Expand Down Expand Up @@ -487,6 +482,12 @@ async def _expand_workflow_tokens_impl(tokens, match_active=True):
'currently supported.'
)

# import only when needed to avoid slowing CLI unnecessarily
from cylc.flow.network.scan import (
filter_name,
is_active,
scan,
)
# construct the pipe
pipe = scan | filter_name(fnmatch.translate(tokens['workflow']))
if match_active is not None:
Expand Down
2 changes: 1 addition & 1 deletion cylc/flow/job_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from cylc.flow import __version__ as CYLC_VERSION
from cylc.flow.job_runner_mgr import JobRunnerManager
import cylc.flow.flags
from cylc.flow.option_parsers import verbosity_to_env
from cylc.flow.log_level import verbosity_to_env
from cylc.flow.config import interpolate_template, ParamExpandError

# the maximum number of task dependencies which Cylc will list before
Expand Down
9 changes: 6 additions & 3 deletions cylc/flow/job_runner_handlers/documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@
not intended to be subclassed.
"""

import re
from typing import (
Iterable,
List,
Tuple,
TYPE_CHECKING,
)

if TYPE_CHECKING:
import re


class ExampleHandler():
"""Documentation for writing job runner handlers.
Expand Down Expand Up @@ -258,15 +261,15 @@ class QSUBHandler(PBSHandler):

"""

REC_ID_FROM_SUBMIT_OUT: re.Pattern
REC_ID_FROM_SUBMIT_OUT: 're.Pattern'
"""Regular expression to extract job IDs from submission stderr.

A regular expression (compiled) to extract the job "id" from the standard
output or standard error of the job submission command.

"""

REC_ID_FROM_SUBMIT_ERR: re.Pattern
REC_ID_FROM_SUBMIT_ERR: 're.Pattern'
"""Regular expression to extract job IDs from submission stderr.

See :py:attr:`ExampleHandler.REC_ID_FROM_SUBMIT_OUT`.
Expand Down
116 changes: 116 additions & 0 deletions cylc/flow/log_level.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# THIS FILE IS PART OF THE CYLC WORKFLOW ENGINE.
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Utilities for configuring logging level via the CLI."""

import logging
from typing import List, Dict, Union, TYPE_CHECKING

if TYPE_CHECKING:
import os


def verbosity_to_log_level(verb: int) -> int:
"""Convert Cylc verbosity to log severity level."""
if verb < 0:
return logging.WARNING
if verb > 0:
return logging.DEBUG
return logging.INFO


def log_level_to_verbosity(lvl: int) -> int:
"""Convert log severity level to Cylc verbosity.

Examples:
>>> log_level_to_verbosity(logging.NOTSET)
2
>>> log_level_to_verbosity(logging.DEBUG)
1
>>> log_level_to_verbosity(logging.INFO)
0
>>> log_level_to_verbosity(logging.WARNING)
-1
>>> log_level_to_verbosity(logging.ERROR)
-1
"""
if lvl < logging.DEBUG:
return 2
if lvl < logging.INFO:
return 1
if lvl == logging.INFO:
return 0
return -1


def verbosity_to_opts(verb: int) -> List[str]:
"""Convert Cylc verbosity to the CLI opts required to replicate it.

Examples:
>>> verbosity_to_opts(0)
[]
>>> verbosity_to_opts(-2)
['-q', '-q']
>>> verbosity_to_opts(2)
['-v', '-v']

"""
return [
'-q'
for _ in range(verb, 0)
] + [
'-v'
for _ in range(0, verb)
]


def verbosity_to_env(verb: int) -> Dict[str, str]:
"""Convert Cylc verbosity to the env vars required to replicate it.

Examples:
>>> verbosity_to_env(0)
{'CYLC_VERBOSE': 'false', 'CYLC_DEBUG': 'false'}
>>> verbosity_to_env(1)
{'CYLC_VERBOSE': 'true', 'CYLC_DEBUG': 'false'}
>>> verbosity_to_env(2)
{'CYLC_VERBOSE': 'true', 'CYLC_DEBUG': 'true'}

"""
return {
'CYLC_VERBOSE': str((verb > 0)).lower(),
'CYLC_DEBUG': str((verb > 1)).lower(),
}


def env_to_verbosity(env: 'Union[Dict, os._Environ]') -> int:
"""Extract verbosity from environment variables.

Examples:
>>> env_to_verbosity({})
0
>>> env_to_verbosity({'CYLC_VERBOSE': 'true'})
1
>>> env_to_verbosity({'CYLC_DEBUG': 'true'})
2
>>> env_to_verbosity({'CYLC_DEBUG': 'TRUE'})
2

"""
return (
2 if env.get('CYLC_DEBUG', '').lower() == 'true'
else 1 if env.get('CYLC_VERBOSE', '').lower() == 'true'
else 0
)
4 changes: 2 additions & 2 deletions cylc/flow/network/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from time import sleep
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Union

from graphql.execution import ExecutionResult
from graphql.execution.executors.asyncio import AsyncioExecutor
import zmq
from zmq.auth.thread import ThreadAuthenticator
Expand All @@ -41,6 +40,7 @@

if TYPE_CHECKING:
from cylc.flow.scheduler import Scheduler
from graphql.execution import ExecutionResult


# maps server methods to the protobuf message (for client/UIS import)
Expand Down Expand Up @@ -368,7 +368,7 @@ def graphql(
object: Execution result, or a list with errors.
"""
try:
executed: ExecutionResult = schema.execute(
executed: 'ExecutionResult' = schema.execute(
request_string,
variable_values=variables,
context_value={
Expand Down
99 changes: 5 additions & 94 deletions cylc/flow/option_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

import sys
from textwrap import dedent
from typing import Any, Dict, Optional, List, Tuple, Union
from typing import Any, Dict, Optional, List, Tuple

from cylc.flow import LOG
from cylc.flow.terminal import supports_color, DIM
Expand All @@ -42,6 +42,10 @@
CylcLogFormatter,
setup_segregated_log_streams,
)
from cylc.flow.log_level import (
env_to_verbosity,
verbosity_to_log_level
)

WORKFLOW_ID_ARG_DOC = ('WORKFLOW', 'Workflow ID')
WORKFLOW_ID_MULTI_ARG_DOC = ('WORKFLOW ...', 'Workflow ID(s)')
Expand Down Expand Up @@ -177,99 +181,6 @@ def format_help_headings(string):
)


def verbosity_to_log_level(verb: int) -> int:
"""Convert Cylc verbosity to log severity level."""
if verb < 0:
return logging.WARNING
if verb > 0:
return logging.DEBUG
return logging.INFO


def log_level_to_verbosity(lvl: int) -> int:
"""Convert log severity level to Cylc verbosity.

Examples:
>>> log_level_to_verbosity(logging.NOTSET)
2
>>> log_level_to_verbosity(logging.DEBUG)
1
>>> log_level_to_verbosity(logging.INFO)
0
>>> log_level_to_verbosity(logging.WARNING)
-1
>>> log_level_to_verbosity(logging.ERROR)
-1
"""
if lvl < logging.DEBUG:
return 2
if lvl < logging.INFO:
return 1
if lvl == logging.INFO:
return 0
return -1


def verbosity_to_opts(verb: int) -> List[str]:
"""Convert Cylc verbosity to the CLI opts required to replicate it.

Examples:
>>> verbosity_to_opts(0)
[]
>>> verbosity_to_opts(-2)
['-q', '-q']
>>> verbosity_to_opts(2)
['-v', '-v']

"""
return [
'-q'
for _ in range(verb, 0)
] + [
'-v'
for _ in range(0, verb)
]


def verbosity_to_env(verb: int) -> Dict[str, str]:
"""Convert Cylc verbosity to the env vars required to replicate it.

Examples:
>>> verbosity_to_env(0)
{'CYLC_VERBOSE': 'false', 'CYLC_DEBUG': 'false'}
>>> verbosity_to_env(1)
{'CYLC_VERBOSE': 'true', 'CYLC_DEBUG': 'false'}
>>> verbosity_to_env(2)
{'CYLC_VERBOSE': 'true', 'CYLC_DEBUG': 'true'}

"""
return {
'CYLC_VERBOSE': str((verb > 0)).lower(),
'CYLC_DEBUG': str((verb > 1)).lower(),
}


def env_to_verbosity(env: Union[Dict, os._Environ]) -> int:
"""Extract verbosity from environment variables.

Examples:
>>> env_to_verbosity({})
0
>>> env_to_verbosity({'CYLC_VERBOSE': 'true'})
1
>>> env_to_verbosity({'CYLC_DEBUG': 'true'})
2
>>> env_to_verbosity({'CYLC_DEBUG': 'TRUE'})
2

"""
return (
2 if env.get('CYLC_DEBUG', '').lower() == 'true'
else 1 if env.get('CYLC_VERBOSE', '').lower() == 'true'
else 0
)


class CylcOption(Option):
"""Optparse option which adds a decrement action."""

Expand Down
Loading
Loading