summaryrefslogtreecommitdiff
path: root/venv/lib/python3.11/site-packages/faker/sphinx
diff options
context:
space:
mode:
Diffstat (limited to 'venv/lib/python3.11/site-packages/faker/sphinx')
-rw-r--r--venv/lib/python3.11/site-packages/faker/sphinx/__init__.py0
-rw-r--r--venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/__init__.cpython-311.pycbin196 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/autodoc.cpython-311.pycbin1334 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/docstring.cpython-311.pycbin11983 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/documentor.cpython-311.pycbin10310 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/validator.cpython-311.pycbin7769 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/faker/sphinx/autodoc.py19
-rw-r--r--venv/lib/python3.11/site-packages/faker/sphinx/docstring.py224
-rw-r--r--venv/lib/python3.11/site-packages/faker/sphinx/documentor.py170
-rw-r--r--venv/lib/python3.11/site-packages/faker/sphinx/validator.py151
10 files changed, 0 insertions, 564 deletions
diff --git a/venv/lib/python3.11/site-packages/faker/sphinx/__init__.py b/venv/lib/python3.11/site-packages/faker/sphinx/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/venv/lib/python3.11/site-packages/faker/sphinx/__init__.py
+++ /dev/null
diff --git a/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/__init__.cpython-311.pyc
deleted file mode 100644
index 932cf92..0000000
--- a/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/__init__.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/autodoc.cpython-311.pyc b/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/autodoc.cpython-311.pyc
deleted file mode 100644
index a750b3c..0000000
--- a/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/autodoc.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/docstring.cpython-311.pyc b/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/docstring.cpython-311.pyc
deleted file mode 100644
index af17c1f..0000000
--- a/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/docstring.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/documentor.cpython-311.pyc b/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/documentor.cpython-311.pyc
deleted file mode 100644
index 8e275af..0000000
--- a/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/documentor.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/validator.cpython-311.pyc b/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/validator.cpython-311.pyc
deleted file mode 100644
index e36eb63..0000000
--- a/venv/lib/python3.11/site-packages/faker/sphinx/__pycache__/validator.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/faker/sphinx/autodoc.py b/venv/lib/python3.11/site-packages/faker/sphinx/autodoc.py
deleted file mode 100644
index 8e7154e..0000000
--- a/venv/lib/python3.11/site-packages/faker/sphinx/autodoc.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# coding=utf-8
-from faker.sphinx.docstring import ProviderMethodDocstring
-from faker.sphinx.documentor import write_provider_docs
-
-
-def _create_source_files(app):
- write_provider_docs()
-
-
-def _process_docstring(app, what, name, obj, options, lines):
- docstring = ProviderMethodDocstring(app, what, name, obj, options, lines)
- if not docstring.skipped:
- lines[:] = docstring.lines[:]
-
-
-def setup(app):
- app.setup_extension("sphinx.ext.autodoc")
- app.connect("builder-inited", _create_source_files)
- app.connect("autodoc-process-docstring", _process_docstring)
diff --git a/venv/lib/python3.11/site-packages/faker/sphinx/docstring.py b/venv/lib/python3.11/site-packages/faker/sphinx/docstring.py
deleted file mode 100644
index 813dbf4..0000000
--- a/venv/lib/python3.11/site-packages/faker/sphinx/docstring.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# coding=utf-8
-import inspect
-import logging
-import re
-
-from collections import namedtuple
-from typing import Pattern
-
-from faker import Faker
-from faker.config import AVAILABLE_LOCALES, DEFAULT_LOCALE
-from faker.sphinx.validator import SampleCodeValidator
-
-logger = logging.getLogger(__name__)
-_fake = Faker(AVAILABLE_LOCALES)
-_base_provider_method_pattern: Pattern = re.compile(r"^faker\.providers\.BaseProvider\.(?P<method>\w+)$")
-_standard_provider_method_pattern: Pattern = re.compile(r"^faker\.providers\.\w+\.Provider\.(?P<method>\w+)$")
-_locale_provider_method_pattern: Pattern = re.compile(
- r"^faker\.providers\.\w+" r"\.(?P<locale>[a-z]{2,3}_[A-Z]{2})" r"\.Provider" r"\.(?P<method>\w+)$",
-)
-_sample_line_pattern: Pattern = re.compile(
- r"^:sample" r"(?: size=(?P<size>[1-9][0-9]*))?" r"(?: seed=(?P<seed>[0-9]+))?" r":" r"(?: ?(?P<kwargs>.*))?$",
-)
-_command_template = "generator.{method}({kwargs})"
-_sample_output_template = (
- ">>> Faker.seed({seed})\n"
- ">>> for _ in range({size}):\n"
- "... fake.{method}({kwargs})\n"
- "...\n"
- "{results}\n\n"
-)
-
-DEFAULT_SAMPLE_SIZE = 5
-DEFAULT_SEED = 0
-Sample = namedtuple("Sample", ["size", "seed", "kwargs"])
-
-
-class ProviderMethodDocstring:
- """
- Class that preprocesses provider method docstrings to generate sample usage and output
-
- Notes on how samples are generated:
- - If the docstring belongs to a standard provider method, sample usage and output will be
- generated using a `Faker` object in the `DEFAULT_LOCALE`.
- - If the docstring belongs to a localized provider method, the correct locale will be used.
- - If the docstring does not belong to any provider method, docstring preprocessing will be skipped.
- - Docstring lines will be parsed for potential sample sections, and the generation details of each
- sample section will internally be represented as a ``Sample`` namedtuple.
- - Each ``Sample`` will have info on the keyword arguments to pass to the provider method, how many
- times the provider method will be called, and the initial seed value to ``Faker.seed()``.
- """
-
- def __init__(self, app, what, name, obj, options, lines):
- self._line_iter = iter(lines)
- self._parsed_lines = []
- self._samples = []
- self._skipped = True
- self._log_prefix = f"{inspect.getfile(obj)}:docstring of {name}: WARNING:"
-
- if what != "method":
- return
-
- base_provider_method_match = _base_provider_method_pattern.match(name)
- locale_provider_method_match = _locale_provider_method_pattern.match(name)
- standard_provider_method_match = _standard_provider_method_pattern.match(name)
- if base_provider_method_match:
- groupdict = base_provider_method_match.groupdict()
- self._method = groupdict["method"]
- self._locale = DEFAULT_LOCALE
- elif standard_provider_method_match:
- groupdict = standard_provider_method_match.groupdict()
- self._method = groupdict["method"]
- self._locale = DEFAULT_LOCALE
- elif locale_provider_method_match:
- groupdict = locale_provider_method_match.groupdict()
- self._method = groupdict["method"]
- self._locale = groupdict["locale"]
- else:
- return
-
- self._skipped = False
- self._parse()
- self._generate_samples()
-
- def _log_warning(self, warning):
- logger.warning(f"{self._log_prefix} {warning}")
-
- def _parse(self):
- while True:
- try:
- line = next(self._line_iter)
- except StopIteration:
- break
- else:
- self._parse_section(line)
-
- def _parse_section(self, section):
- # No-op if section does not look like the start of a sample section
- if not section.startswith(":sample"):
- self._parsed_lines.append(section)
- return
-
- try:
- next_line = next(self._line_iter)
- except StopIteration:
- # No more lines left to consume, so save current sample section
- self._process_sample_section(section)
- return
-
- # Next line is the start of a new sample section, so process
- # current sample section, and start parsing the new section
- if next_line.startswith(":sample"):
- self._process_sample_section(section)
- self._parse_section(next_line)
-
- # Next line is an empty line indicating the end of
- # current sample section, so process current section
- elif next_line == "":
- self._process_sample_section(section)
-
- # Section is assumed to be multiline, so continue
- # adding lines to current sample section
- else:
- section = section + next_line
- self._parse_section(section)
-
- def _process_sample_section(self, section):
- match = _sample_line_pattern.match(section)
-
- # Discard sample section if malformed
- if not match:
- msg = f"The section `{section}` is malformed and will be discarded."
- self._log_warning(msg)
- return
-
- # Set sample generation defaults and do some beautification if necessary
- groupdict = match.groupdict()
- size = groupdict.get("size")
- seed = groupdict.get("seed")
- kwargs = groupdict.get("kwargs")
- size = max(int(size), DEFAULT_SAMPLE_SIZE) if size else DEFAULT_SAMPLE_SIZE
- seed = int(seed) if seed else DEFAULT_SEED
- kwargs = self._beautify_kwargs(kwargs) if kwargs else ""
-
- # Store sample generation details
- sample = Sample(size, seed, kwargs)
- self._samples.append(sample)
-
- def _beautify_kwargs(self, kwargs):
- def _repl_whitespace(match):
- quoted = match.group(1) or match.group(2)
- return quoted if quoted else ""
-
- def _repl_comma(match):
- quoted = match.group(1) or match.group(2)
- return quoted if quoted else ", "
-
- # First, remove all whitespaces and tabs not within quotes
- result = re.sub(r'("[^"]*")|(\'[^\']*\')|[ \t]+', _repl_whitespace, kwargs)
-
- # Next, insert a whitespace after each comma not within quotes
- result = re.sub(r'("[^"]*")|(\'[^\']*\')|,', _repl_comma, result)
-
- # Then return the result with all leading and trailing whitespaces stripped
- return result.strip()
-
- def _stringify_result(self, value):
- return repr(value)
-
- def _generate_eval_scope(self):
- from collections import OrderedDict # noqa: F401 Do not remove! The eval command needs this reference.
-
- return {
- "generator": _fake[self._locale],
- "OrderedDict": OrderedDict,
- }
-
- def _inject_default_sample_section(self):
- default_sample = Sample(DEFAULT_SAMPLE_SIZE, DEFAULT_SEED, "")
- self._samples.append(default_sample)
-
- def _generate_samples(self):
- if not self._samples:
- self._inject_default_sample_section()
-
- output = ""
- eval_scope = self._generate_eval_scope()
- for sample in self._samples:
- command = _command_template.format(method=self._method, kwargs=sample.kwargs)
- validator = SampleCodeValidator(command)
- if validator.errors:
- msg = (
- f"Invalid code elements detected. Sample generation will be "
- f"skipped for method `{self._method}` with arguments `{sample.kwargs}`."
- )
- self._log_warning(msg)
- continue
-
- try:
- Faker.seed(sample.seed)
- results = "\n".join([self._stringify_result(eval(command, eval_scope)) for _ in range(sample.size)])
- except Exception:
- msg = f"Sample generation failed for method `{self._method}` with arguments `{sample.kwargs}`."
- self._log_warning(msg)
- continue
- else:
- output += _sample_output_template.format(
- seed=sample.seed,
- method=self._method,
- kwargs=sample.kwargs,
- size=sample.size,
- results=results,
- )
-
- if output:
- output = ":examples:\n\n" + output
- self._parsed_lines.extend(output.split("\n"))
-
- @property
- def skipped(self):
- return self._skipped
-
- @property
- def lines(self):
- return self._parsed_lines
diff --git a/venv/lib/python3.11/site-packages/faker/sphinx/documentor.py b/venv/lib/python3.11/site-packages/faker/sphinx/documentor.py
deleted file mode 100644
index ad6d7ab..0000000
--- a/venv/lib/python3.11/site-packages/faker/sphinx/documentor.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# coding=utf-8
-import importlib
-import inspect
-import os
-
-from pathlib import Path
-
-from faker.config import AVAILABLE_LOCALES
-from faker.config import PROVIDERS as STANDARD_PROVIDER_NAMES
-from faker.providers import BaseProvider
-
-if os.environ.get("READTHEDOCS", False):
- version = os.environ["READTHEDOCS_VERSION"]
- HOME = Path("/home/docs/checkouts/readthedocs.org/user_builds/faker/checkouts") / version
- DOCS_ROOT = HOME / "docs"
-else:
- DOCS_ROOT = Path(__file__).resolve().parents[2] / "docs"
-
-SECTION_ADORNMENTS = "#*=-~"
-
-PROVIDER_AUTODOC_TEMPLATE = """
-.. autoclass:: {provider_class}
- :members: {provider_methods}
- :undoc-members:
- :show-inheritance:
-
-"""
-
-BASE_PROVIDER_METHOD_NAMES = [
- name for name, method in inspect.getmembers(BaseProvider, inspect.isfunction) if not name.startswith("_")
-]
-
-
-def _get_provider_methods(provider_class):
- try:
- provider_module_name, obj_name = provider_class.rsplit(".", 1)
- provider_module = importlib.import_module(provider_module_name)
- provider = getattr(provider_module, obj_name, None)
- except (ModuleNotFoundError, AttributeError):
- return ""
- else:
- return ", ".join(
- [
- name
- for name, method in inspect.getmembers(provider, inspect.isfunction)
- if not name.startswith("_") and name not in BASE_PROVIDER_METHOD_NAMES
- ]
- )
-
-
-def _get_localized_provider_info(locale):
- info = []
- for provider_name in STANDARD_PROVIDER_NAMES:
- try:
- locale_module_path = f"{provider_name}.{locale}"
- locale_module = importlib.import_module(locale_module_path)
- provider = getattr(locale_module, "Provider")
- except (ModuleNotFoundError, AttributeError):
- continue
- else:
- provider_class = f"{provider.__module__}.Provider"
- info.append((provider_class, provider_name))
- return info
-
-
-def _write(fh, s):
- return fh.write(s.encode("utf-8"))
-
-
-def _hide_edit_on_github(fh):
- _write(fh, ":github_url: hide\n\n")
-
-
-def _write_title(fh, title, level=1):
- if not isinstance(level, int) or level < 1 or level > 5:
- raise ValueError("`level` must be an integer from 1 to 5")
- if level <= 2:
- _write(fh, SECTION_ADORNMENTS[level - 1] * len(title))
- _write(fh, "\n")
- _write(fh, f"{title}\n")
- _write(fh, SECTION_ADORNMENTS[level - 1] * len(title))
- _write(fh, "\n\n")
-
-
-def _write_includes(fh):
- _write(fh, ".. include:: ../includes/substitutions.rst")
- _write(fh, "\n\n")
-
-
-def _write_standard_provider_index():
- with (DOCS_ROOT / "providers.rst").open("wb") as fh:
- _hide_edit_on_github(fh)
- _write_title(fh, "Standard Providers")
- _write(fh, ".. toctree::\n")
- _write(fh, " :maxdepth: 2\n\n")
- _write(fh, " providers/baseprovider\n")
- for provider_name in STANDARD_PROVIDER_NAMES:
- _write(fh, f" providers/{provider_name}\n")
-
-
-def _write_base_provider_docs():
- (DOCS_ROOT / "providers").mkdir(parents=True, exist_ok=True)
- with (DOCS_ROOT / "providers" / "baseprovider.rst").open("wb") as fh:
- _hide_edit_on_github(fh)
- _write_title(fh, "``faker.providers``")
- _write_includes(fh)
- _write(
- fh,
- PROVIDER_AUTODOC_TEMPLATE.format(
- provider_class="faker.providers.BaseProvider",
- provider_methods=",".join(BASE_PROVIDER_METHOD_NAMES),
- ),
- )
-
-
-def _write_standard_provider_docs():
- (DOCS_ROOT / "providers").mkdir(parents=True, exist_ok=True)
- for provider_name in STANDARD_PROVIDER_NAMES:
- with (DOCS_ROOT / "providers" / f"{provider_name}.rst").open("wb") as fh:
- provider_class = f"{provider_name}.Provider"
- provider_methods = _get_provider_methods(provider_class)
- _hide_edit_on_github(fh)
- _write_title(fh, f"``{provider_name}``")
- _write_includes(fh)
- _write(
- fh,
- PROVIDER_AUTODOC_TEMPLATE.format(
- provider_class=provider_class,
- provider_methods=provider_methods,
- ),
- )
-
-
-def _write_localized_provider_index():
- with (DOCS_ROOT / "locales.rst").open("wb") as fh:
- _hide_edit_on_github(fh)
- _write_title(fh, "Localized Providers")
- _write(fh, ".. toctree::\n")
- _write(fh, " :maxdepth: 2\n\n")
- for locale in AVAILABLE_LOCALES:
- _write(fh, f" locales/{locale}\n")
-
-
-def _write_localized_provider_docs():
- (DOCS_ROOT / "locales").mkdir(parents=True, exist_ok=True)
- for locale in AVAILABLE_LOCALES:
- info = _get_localized_provider_info(locale)
- with (DOCS_ROOT / "locales" / "{}.rst".format(locale)).open("wb") as fh:
- _hide_edit_on_github(fh)
- _write_title(fh, f"Locale {locale}")
- _write_includes(fh)
- for provider_class, standard_provider_name in info:
- provider_methods = _get_provider_methods(provider_class)
- _write_title(fh, f"``{standard_provider_name}``", level=2)
- _write(
- fh,
- PROVIDER_AUTODOC_TEMPLATE.format(
- provider_class=provider_class,
- provider_methods=provider_methods,
- ),
- )
-
-
-def write_provider_docs():
- DOCS_ROOT.mkdir(parents=True, exist_ok=True)
- _write_standard_provider_index()
- _write_base_provider_docs()
- _write_standard_provider_docs()
- _write_localized_provider_index()
- _write_localized_provider_docs()
diff --git a/venv/lib/python3.11/site-packages/faker/sphinx/validator.py b/venv/lib/python3.11/site-packages/faker/sphinx/validator.py
deleted file mode 100644
index 05acf89..0000000
--- a/venv/lib/python3.11/site-packages/faker/sphinx/validator.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# coding=utf-8
-import ast
-import traceback
-
-from collections import OrderedDict
-
-
-class SampleCodeValidator(ast.NodeVisitor):
- """
- Class that checks if a string is a valid and "safe" Python expression
-
- What is considered "safe" for this class is limited to the context of generating
- provider method sample code and output for documentation purposes. The end goal
- is to pass a command string to `eval()` should the string pass the validation
- performed by this class.
-
- The main assumption this class will make is that the command string passed during
- class instantiation will always be in the form "{generator}.{method}({arguments})".
- In said form, {generator} is a `Generator` object variable that already exists
- within the scope where `eval()` will be called, {method} will be the provider
- method name which is also available within the `eval()` scope, and {arguments}
- will be sample arguments parsed from docstrings. This means that {arguments} can
- potentially be used as a vector for code injection.
-
- In order to neuter the impact of code injection, the following validation steps
- will be applied:
-
- - The command string is parsed using 'eval' mode, meaning expressions only.
- - The command string can only have whitelisted code elements. See `_whitelisted_nodes`.
- - The command string can only have one instance of variable access.
- - The command string can only have one instance of attribute access.
- - The command string can only have one instance of a function/method call.
- - The argument values in the command string can only be literals.
- - The only literals allowed are numbers (integers, floats, or complex numbers),
- strings (but not f-strings), bytes, lists, tuples, sets, dictionaries, True,
- False, and None.
-
- There is, however, an exception. In order to accommodate sample code with custom
- probability distribution, variable access to `OrderedDict` will not count against
- the maximum limit of variable access, and invoking `OrderedDict` constructor calls
- will not count against the maximum limit of function/method calls. In order to
- neuter the impact of code injection, please ensure that `OrderedDict` refers to
- the standard library's `collections.OrderedDict` within the `eval()` scope before
- passing the command string to `eval()` for execution. This can be done in code review.
- """
-
- _whitelisted_nodes = (
- # Code elements related to function calls and variable and attribute access
- ast.Expression,
- ast.Call,
- ast.Attribute,
- ast.Name,
- ast.Load,
- ast.keyword,
- # Code elements representing whitelisted literals
- ast.Num,
- ast.Str,
- ast.Bytes,
- ast.List,
- ast.Tuple,
- ast.Set,
- ast.Dict,
- ast.NameConstant,
- )
-
- _max_function_call_count = 1
- _max_attribute_access_count = 1
- _max_variable_access_count = 1
-
- def __init__(self, command):
- self._errors = set()
- self._function_call_count = 0
- self._attribute_access_count = 0
- self._variable_access_count = 0
- self._command = command
-
- try:
- self._tree = ast.parse(command, mode="eval")
- except (SyntaxError, ValueError):
- self._log_error(traceback.format_exc())
- else:
- self._validate()
-
- @property
- def errors(self):
- return self._errors
-
- def _is_whitelisted(self, node):
- return isinstance(node, self._whitelisted_nodes)
-
- def _log_error(self, msg):
- self._errors.add(msg)
-
- def _validate(self):
- self.visit(self._tree)
-
- def _is_node_using_ordereddict(self, node):
- is_valid = False
-
- # If instance of function call, check if it is a call to the OrderedDict constructor
- if isinstance(node, ast.Call):
- is_valid = self._is_node_using_ordereddict(node.func)
-
- # If instance of variable access, check if it is
- elif isinstance(node, ast.Name) and node.id == OrderedDict.__name__:
- is_valid = True
-
- return is_valid
-
- def visit(self, node):
- # Check if code element type is allowed
- if not self._is_whitelisted(node):
- msg = "Code element `%s` is not allowed." % node.__class__.__name__
- self._log_error(msg)
-
- return super().visit(node)
-
- def visit_Call(self, node):
- if not self._is_node_using_ordereddict(node):
- # There can only be one instance of a function call
- if self._function_call_count < self._max_function_call_count:
- self._function_call_count += 1
- else:
- msg = "There can only be one instance of a function/method call."
- self._log_error(msg)
-
- # Proceed to child nodes
- self.generic_visit(node)
-
- def visit_Attribute(self, node):
- # There can only be one instance of attribute access
- if self._attribute_access_count < self._max_attribute_access_count:
- self._attribute_access_count += 1
- else:
- msg = "There can only be one instance of attribute access."
- self._log_error(msg)
-
- # Proceed to child nodes
- self.generic_visit(node)
-
- def visit_Name(self, node):
- if not self._is_node_using_ordereddict(node):
- # There can only be one instance of variable access
- if self._variable_access_count < self._max_variable_access_count:
- self._variable_access_count += 1
- else:
- msg = "There can only be one instance of variable access."
- self._log_error(msg)
-
- # Proceed to child nodes
- self.generic_visit(node)