"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "client/configuration.py" between
pyre-check-0.0.54.tar.gz and pyre-check-0.0.55.tar.gz

About: Pyre is a performant type checker for Python (ships with Pysa, a security focused static analysis tool).

configuration.py  (pyre-check-0.0.54):configuration.py  (pyre-check-0.0.55)
skipping to change at line 37 skipping to change at line 37
CONFIGURATION_FILE, CONFIGURATION_FILE,
LOCAL_CONFIGURATION_FILE, LOCAL_CONFIGURATION_FILE,
find_parent_directory_containing_file, find_parent_directory_containing_file,
find_typeshed, find_typeshed,
get_relative_local_root, get_relative_local_root,
) )
from .resources import LOG_DIRECTORY from .resources import LOG_DIRECTORY
LOG: Logger = logging.getLogger(__name__) LOG: Logger = logging.getLogger(__name__)
def _relativize_root(root: str, project_root: str, relative_root: Optional[str])
-> str:
if root.startswith("//"):
return expand_relative_path(project_root, root[2:])
else:
return expand_relative_path(relative_root or "", root)
class InvalidConfiguration(Exception): class InvalidConfiguration(Exception):
def __init__(self, message: str) -> None: def __init__(self, message: str) -> None:
self.message = f"Invalid configuration: {message}" self.message = f"Invalid configuration: {message}"
super().__init__(self.message) super().__init__(self.message)
class SearchPathElement: class SearchPathElement:
def __init__(self, root: str, subdirectory: Optional[str]) -> None: def __init__(self, root: str, subdirectory: Optional[str]) -> None:
self.root = root self.root = root
self.subdirectory = subdirectory self.subdirectory = subdirectory
@staticmethod @staticmethod
def expand( def expand(
path: Union[Dict[str, str], str], path: Union[Dict[str, str], str],
project_root: str, project_root: str,
path_relative_to: Optional[str] = None, path_relative_to: Optional[str] = None,
) -> "SearchPathElement": ) -> "SearchPathElement":
if isinstance(path, str): if isinstance(path, str):
return SearchPathElement( return SearchPathElement(
root=SearchPathElement.relativize_root( _relativize_root(path, project_root, path_relative_to),
path, project_root, path_relative_to
),
subdirectory=None, subdirectory=None,
) )
else: else:
if "root" in path and "subdirectory" in path: if "root" in path and "subdirectory" in path:
root = path["root"] root = path["root"]
subdirectory = path["subdirectory"] subdirectory = path["subdirectory"]
return SearchPathElement( return SearchPathElement(
root=SearchPathElement.relativize_root( _relativize_root(root, project_root, path_relative_to),
root, project_root, path_relative_to
),
subdirectory=subdirectory, subdirectory=subdirectory,
) )
elif "site-package" in path: elif "site-package" in path:
site_root = site.getsitepackages() site_root = site.getsitepackages()
subdirectory = path["site-package"] subdirectory = path["site-package"]
found_element = None found_element = None
for root in site_root: for root in site_root:
site_package_element = SearchPathElement( site_package_element = SearchPathElement(
root=SearchPathElement.relativize_root( _relativize_root(root, project_root, None),
root, project_root, None
),
subdirectory=subdirectory, subdirectory=subdirectory,
) )
if os.path.isdir(site_package_element.path()): if os.path.isdir(site_package_element.path()):
found_element = site_package_element found_element = site_package_element
if found_element is None: if found_element is None:
raise InvalidConfiguration( raise InvalidConfiguration(
f"Cannot find site package '{subdirectory}'" f"Cannot find site package '{subdirectory}'"
) )
return found_element return found_element
else: else:
raise InvalidConfiguration( raise InvalidConfiguration(
"Search path elements must have `root` and `subdirectory` " "Search path elements must have `root` and `subdirectory` "
"specified." "specified."
) )
@staticmethod
def relativize_root(
root: str, project_root: str, relative_root: Optional[str]
) -> str:
if root.startswith("//"):
return expand_relative_path(project_root, root[2:])
else:
return expand_relative_path(relative_root or "", root)
def path(self) -> str: def path(self) -> str:
subdirectory = self.subdirectory subdirectory = self.subdirectory
if subdirectory is not None: if subdirectory is not None:
return os.path.join(self.root, subdirectory) return os.path.join(self.root, subdirectory)
else: else:
return self.root return self.root
def command_line_argument(self) -> str: def command_line_argument(self) -> str:
subdirectory = self.subdirectory subdirectory = self.subdirectory
if subdirectory is not None: if subdirectory is not None:
skipping to change at line 211 skipping to change at line 202
excludes: Optional[List[str]] = None, excludes: Optional[List[str]] = None,
strict: bool = False, strict: bool = False,
formatter: Optional[str] = None, formatter: Optional[str] = None,
logger: Optional[str] = None, logger: Optional[str] = None,
use_buck_source_database: Optional[bool] = None, use_buck_source_database: Optional[bool] = None,
) -> None: ) -> None:
self.source_directories = [] self.source_directories = []
self.targets = [] self.targets = []
self.logger = logger self.logger = logger
self.formatter = formatter self.formatter = formatter
self.ignore_all_errors = [] self._ignore_all_errors = []
self.number_of_workers: int = 0 self.number_of_workers: int = 0
self.project_root: str = project_root self.project_root: str = project_root
self._local_root: Optional[str] = local_root self._local_root: Optional[str] = local_root
self.taint_models_path: List[str] = [] self.taint_models_path: List[str] = []
self.file_hash: Optional[str] = None self.file_hash: Optional[str] = None
self.extensions: List[str] = [] self.extensions: List[str] = []
self.dot_pyre_directory: Path = dot_pyre_directory self.dot_pyre_directory: Path = dot_pyre_directory
relative_local_root = get_relative_local_root( relative_local_root = get_relative_local_root(
Path(project_root), Path(local_root) if local_root is not None else None Path(project_root), Path(local_root) if local_root is not None else None
skipping to change at line 238 skipping to change at line 229
) )
self._version_hash: Optional[str] = None self._version_hash: Optional[str] = None
self._binary: Optional[str] = None self._binary: Optional[str] = None
self._typeshed: Optional[str] = None self._typeshed: Optional[str] = None
self._buck_builder_binary: Optional[str] = None self._buck_builder_binary: Optional[str] = None
self.strict: bool = strict self.strict: bool = strict
self._use_buck_builder: Optional[bool] = use_buck_builder self._use_buck_builder: Optional[bool] = use_buck_builder
self._use_buck_source_database: Optional[bool] = use_buck_source_databas e self._use_buck_source_database: Optional[bool] = use_buck_source_databas e
self.ignore_infer: List[str] = [] self.ignore_infer: List[str] = []
self.do_not_ignore_errors_in: List[str] = [] self._do_not_ignore_errors_in: List[str] = []
self._search_path: List[SearchPathElement] = [] self._search_path: List[SearchPathElement] = []
if search_path: if search_path:
search_path_elements = [ search_path_elements = [
SearchPathElement.expand(path, project_root=project_root) SearchPathElement.expand(path, project_root=project_root)
for path in search_path for path in search_path
] ]
self._search_path.extend(search_path_elements) self._search_path.extend(search_path_elements)
# We will extend the search path further, with the config file # We will extend the search path further, with the config file
# items, inside _read(). # items, inside _read().
skipping to change at line 327 skipping to change at line 318
isinstance(element, str) for element in list isinstance(element, str) for element in list
) )
if not is_list_of_strings(self.source_directories) or not is_list_of_str ings( if not is_list_of_strings(self.source_directories) or not is_list_of_str ings(
self.targets self.targets
): ):
raise InvalidConfiguration( raise InvalidConfiguration(
"`target` and `source_directories` fields must be lists of " "st rings." "`target` and `source_directories` fields must be lists of " "st rings."
) )
if not is_list_of_strings(self.ignore_all_errors): if not is_list_of_strings(self._ignore_all_errors):
raise InvalidConfiguration( raise InvalidConfiguration(
"`ignore_all_errors` field must be a list of strings." "`ignore_all_errors` field must be a list of strings."
) )
if not is_list_of_strings(self.ignore_infer): if not is_list_of_strings(self.ignore_infer):
raise InvalidConfiguration( raise InvalidConfiguration(
"`ignore_infer` field must be a list of strings." "`ignore_infer` field must be a list of strings."
) )
if not is_list_of_strings(self.extensions): if not is_list_of_strings(self.extensions):
skipping to change at line 363 skipping to change at line 354
assert_readable_directory_in_configuration(self.typeshed, field_name="ty peshed") assert_readable_directory_in_configuration(self.typeshed, field_name="ty peshed")
# A courtesy warning since we have changed default behaviour. # A courtesy warning since we have changed default behaviour.
if self._typeshed_has_obsolete_value(): if self._typeshed_has_obsolete_value():
LOG.warning( LOG.warning(
f"It appears that `{self.typeshed}` points at a `stdlib` " f"It appears that `{self.typeshed}` points at a `stdlib` "
"directory. Please note that the `typeshed` configuration must " "directory. Please note that the `typeshed` configuration must "
"point to the root of the `typeshed` directory." "point to the root of the `typeshed` directory."
) )
expanded_ignore_paths = []
for path in self.ignore_all_errors:
expanded = glob.glob(path)
if not expanded:
expanded_ignore_paths.append(path)
else:
expanded_ignore_paths += expanded
self.ignore_all_errors = expanded_ignore_paths
non_existent_ignore_paths = [
path for path in self.ignore_all_errors if not os.path.exists(path)
]
if non_existent_ignore_paths:
LOG.warning(
"Nonexistent paths passed in to `ignore_all_errors`: "
f"`{non_existent_ignore_paths}`"
)
self.ignore_all_errors = [
path
for path in self.ignore_all_errors
if path not in non_existent_ignore_paths
]
non_existent_infer_paths = [ non_existent_infer_paths = [
path for path in self.ignore_infer if not os.path.exists(path) path for path in self.ignore_infer if not os.path.exists(path)
] ]
if non_existent_infer_paths: if non_existent_infer_paths:
LOG.warning( LOG.warning(
"Nonexistent paths passed in to `ignore_infer`: " "Nonexistent paths passed in to `ignore_infer`: "
f"`{non_existent_infer_paths}`" f"`{non_existent_infer_paths}`"
) )
self.ignore_infer = [ self.ignore_infer = [
path path
skipping to change at line 428 skipping to change at line 396
for element in self._search_path: for element in self._search_path:
assert_readable_directory_in_configuration( assert_readable_directory_in_configuration(
element.path(), field_name="search_path" element.path(), field_name="search_path"
) )
if not is_list_of_strings(self.other_critical_files): if not is_list_of_strings(self.other_critical_files):
raise InvalidConfiguration( raise InvalidConfiguration(
"`critical_files` field must be a list of strings." "`critical_files` field must be a list of strings."
) )
if not is_list_of_strings(self.do_not_ignore_errors_in): if not is_list_of_strings(self._do_not_ignore_errors_in):
raise InvalidConfiguration( raise InvalidConfiguration(
"`do_not_ignore_errors_in` field must be a list of strings." "`do_not_ignore_errors_in` field must be a list of strings."
) )
for directory_name in self.do_not_ignore_errors_in:
assert_readable_directory_in_configuration(directory_name)
@property @property
def version_hash(self) -> str: def version_hash(self) -> str:
return self._version_hash or "unversioned" return self._version_hash or "unversioned"
@property @property
def binary(self) -> str: def binary(self) -> str:
binary = self._binary binary = self._binary
if not binary: if not binary:
raise InvalidConfiguration("No binary specified.") raise InvalidConfiguration("No binary specified.")
skipping to change at line 475 skipping to change at line 441
@property @property
def search_path(self) -> List[str]: def search_path(self) -> List[str]:
if not self._search_path: if not self._search_path:
return [] return []
return [element.command_line_argument() for element in self._search_path ] return [element.command_line_argument() for element in self._search_path ]
@property @property
def local_root(self) -> Optional[str]: def local_root(self) -> Optional[str]:
return self._local_root return self._local_root
def get_existent_do_not_ignore_errors_in_paths(self) -> List[str]:
"""
This is a separate method because we want to check for existing files
at the time this is called, not when the configuration is
constructed.
"""
ignore_paths = [
_relativize_root(path, project_root=self.project_root, relative_root
=None)
for path in self._do_not_ignore_errors_in
]
paths = [path for path in ignore_paths if os.path.exists(path)]
non_existent_paths = set(ignore_paths) - set(paths)
if non_existent_paths:
LOG.debug(
"Filtering out nonexistent paths in `do_not_ignore_errors_in`: "
f"{non_existent_paths}"
)
return paths
def get_existent_ignore_all_errors_paths(self) -> List[str]:
"""
This is a separate method because we want to check for existing files
at the time this is called, not when the configuration is
constructed.
"""
expanded_ignore_paths = []
for path in self._ignore_all_errors:
rooted_path = _relativize_root(
path, project_root=self.project_root, relative_root=None
)
expanded = glob.glob(rooted_path)
if not expanded:
expanded_ignore_paths.append(path)
else:
expanded_ignore_paths += expanded
non_existent_ignore_paths = [
path for path in expanded_ignore_paths if not os.path.exists(path)
]
if non_existent_ignore_paths:
LOG.warning(
"Nonexistent paths passed in to `ignore_all_errors`: "
f"`{non_existent_ignore_paths}`"
)
expanded_ignore_paths = [
path
for path in expanded_ignore_paths
if path not in non_existent_ignore_paths
]
return expanded_ignore_paths
def get_binary_version(self) -> Optional[str]: def get_binary_version(self) -> Optional[str]:
status = subprocess.run( status = subprocess.run(
[self.binary, "-version"], stdout=subprocess.PIPE, universal_newline s=True [self.binary, "-version"], stdout=subprocess.PIPE, universal_newline s=True
) )
if status.returncode == 0: if status.returncode == 0:
return status.stdout.strip() return status.stdout.strip()
else: else:
return None return None
def _check_nested_configurations(self, local_root: str) -> None: def _check_nested_configurations(self, local_root: str) -> None:
skipping to change at line 509 skipping to change at line 526
search_path=[search_path.root for search_path in self._search_pa th], search_path=[search_path.root for search_path in self._search_pa th],
binary=self._binary, binary=self._binary,
typeshed=self._typeshed, typeshed=self._typeshed,
buck_builder_binary=self._buck_builder_binary, buck_builder_binary=self._buck_builder_binary,
excludes=self.excludes, excludes=self.excludes,
logger=self.logger, logger=self.logger,
formatter=self.formatter, formatter=self.formatter,
dot_pyre_directory=self.dot_pyre_directory, dot_pyre_directory=self.dot_pyre_directory,
) )
paths_to_ignore = list(local_root.parents) + [local_root] paths_to_ignore = list(local_root.parents) + [local_root]
for ignore_element in parent_local_configuration.ignore_all_errors: for (
ignore_element
) in parent_local_configuration.get_existent_ignore_all_errors_paths
():
if Path(ignore_element).resolve() in paths_to_ignore: if Path(ignore_element).resolve() in paths_to_ignore:
excluded_from_parent = True excluded_from_parent = True
except InvalidConfiguration as error: except InvalidConfiguration as error:
parent_error = error parent_error = error
if not excluded_from_parent: if not excluded_from_parent:
relative_path = str(local_root.relative_to(parent_local_root)) relative_path = str(local_root.relative_to(parent_local_root))
error_message = ( error_message = (
"Local configuration is nested under another local configuration at " "Local configuration is nested under another local configuration at "
f"`{parent_local_root}`.\nPlease add `{relative_path}` to the " f"`{parent_local_root}`.\nPlease add `{relative_path}` to the "
skipping to change at line 586 skipping to change at line 605
self.formatter = configuration.consume( self.formatter = configuration.consume(
"formatter", current=self.formatter "formatter", current=self.formatter
) )
self.strict = configuration.consume("strict", default=self.stric t) self.strict = configuration.consume("strict", default=self.stric t)
ignore_all_errors = configuration.consume( ignore_all_errors = configuration.consume(
"ignore_all_errors", default=[] "ignore_all_errors", default=[]
) )
self.ignore_all_errors.extend(ignore_all_errors) self._ignore_all_errors.extend(ignore_all_errors)
ignore_infer = configuration.consume("ignore_infer", default=[]) ignore_infer = configuration.consume("ignore_infer", default=[])
self.ignore_infer.extend(ignore_infer) self.ignore_infer.extend(ignore_infer)
self.number_of_workers = int( self.number_of_workers = int(
configuration.consume( configuration.consume(
"workers", default=0, current=self.number_of_workers "workers", default=0, current=self.number_of_workers
) )
) )
skipping to change at line 683 skipping to change at line 702
self.autocomplete = configuration.consume("autocomplete", defaul t=False) self.autocomplete = configuration.consume("autocomplete", defaul t=False)
self.other_critical_files = configuration.consume( self.other_critical_files = configuration.consume(
"critical_files", default=[] "critical_files", default=[]
) )
do_not_ignore_errors_in = configuration.consume( do_not_ignore_errors_in = configuration.consume(
"do_not_ignore_errors_in", default=[] "do_not_ignore_errors_in", default=[]
) )
assert isinstance(do_not_ignore_errors_in, list) assert isinstance(do_not_ignore_errors_in, list)
self.do_not_ignore_errors_in.extend(do_not_ignore_errors_in) self._do_not_ignore_errors_in.extend(do_not_ignore_errors_in)
# Warn on deprecated fields. # Warn on deprecated fields.
for deprecated_field in configuration._deprecated.keys(): for deprecated_field in configuration._deprecated.keys():
configuration.consume(deprecated_field) configuration.consume(deprecated_field)
# This block should be at the bottom to be effective. # This block should be at the bottom to be effective.
unused_keys = configuration.unused_keys() unused_keys = configuration.unused_keys()
if unused_keys: if unused_keys:
LOG.warning( LOG.warning(
"Some configuration items were not recognized in " "Some configuration items were not recognized in "
skipping to change at line 716 skipping to change at line 735
def _expand_relative_paths(self, root: str) -> None: def _expand_relative_paths(self, root: str) -> None:
self.source_directories = [ self.source_directories = [
expand_relative_path(root, directory) expand_relative_path(root, directory)
for directory in self.source_directories for directory in self.source_directories
] ]
logger = self.logger logger = self.logger
if logger: if logger:
self.logger = expand_relative_path(root, logger) self.logger = expand_relative_path(root, logger)
self.ignore_all_errors = [ self._ignore_all_errors = [
expand_relative_path(root, path) for path in self.ignore_all_errors expand_relative_path(root, path) for path in self._ignore_all_errors
] ]
self.ignore_infer = [ self.ignore_infer = [
expand_relative_path(root, path) for path in self.ignore_infer expand_relative_path(root, path) for path in self.ignore_infer
] ]
binary = self._binary binary = self._binary
if binary: if binary:
self._binary = expand_relative_path(root, binary) self._binary = expand_relative_path(root, binary)
skipping to change at line 744 skipping to change at line 763
self._typeshed = expand_relative_path(root, typeshed) self._typeshed = expand_relative_path(root, typeshed)
self.taint_models_path = [ self.taint_models_path = [
expand_relative_path(root, path) for path in self.taint_models_path expand_relative_path(root, path) for path in self.taint_models_path
] ]
self.other_critical_files = [ self.other_critical_files = [
expand_relative_path(root, path) for path in self.other_critical_fil es expand_relative_path(root, path) for path in self.other_critical_fil es
] ]
self.do_not_ignore_errors_in = [ self._do_not_ignore_errors_in = [
expand_relative_path(root, path) for path in self.do_not_ignore_erro expand_relative_path(root, path) for path in self._do_not_ignore_err
rs_in ors_in
] ]
def _resolve_versioned_paths(self) -> None: def _resolve_versioned_paths(self) -> None:
version_hash = self.version_hash version_hash = self.version_hash
if not version_hash: if not version_hash:
return return
binary = self._binary binary = self._binary
if binary: if binary:
self._binary = binary.replace("%V", version_hash) self._binary = binary.replace("%V", version_hash)
 End of changes. 17 change blocks. 
55 lines changed or deleted 77 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)