PyCQA / docformatter

Formats docstrings to follow PEP 257
https://pypi.python.org/pypi/docformatter
MIT License
524 stars 61 forks source link

v1.7.2-rc4 - Application of line length limits to reformatted text #228

Closed rmartin16 closed 1 year ago

rmartin16 commented 1 year ago

While testing out v1.7.2-rc4, I realized the reformatted text wasn't always being reformatted to reach the specified line length.

In these examples, the line length is being controlled by the --black setting to a length of 88. It appears there is some length setting that is triggering the reflow of the :param xxx: docs...but it doesn't seem to be the same length controlling how other parts of the docs are changed.

The body of the docstring here is reformatted to reach 88 chars:

 def is_process_dead(pid: int) -> bool:
     """Returns True if a PID is not assigned to a process.

-    Checking if a PID exists is only a semi-safe proxy to determine
-    if a process is dead since PIDs can be re-used. Therefore, this
-    function should only be used via constant monitoring of a PID
-    to identify when the process goes from existing to not existing.
+    Checking if a PID exists is only a semi-safe proxy to determine if a process is dead
+    since PIDs can be re-used. Therefore, this function should only be used via constant
+    monitoring of a PID to identify when the process goes from existing to not existing.

     :param pid: integer value to be checked if assigned as a PID.
     :return: True if PID does not exist; False otherwise.

Here again we see the body being reformatted to 88 chars but the param xxx: docs, while being reformatted, are not being extended to reach the length limit:

class Example:
     def stream_output(
         self,
         label: str,
         popen_process: subprocess.Popen,
         stop_func: Callable[[], bool] = lambda: False,
         filter_func: Callable[[str], Iterator[str]] | None = None,
     ):
         """Stream the output of a Popen process until the process exits. If the user
         sends CTRL+C, the process will be terminated.

-        This is useful for starting a process via Popen such as tailing a
-        log file, then initiating a non-blocking process that populates that
-        log, and finally streaming the original process's output here.
+        This is useful for starting a process via Popen such as tailing a log file, then
+        initiating a non-blocking process that populates that log, and finally streaming
+        the original process's output here.

         :param label: A description of the content being streamed; used for
             to provide context in logging messages.
         :param popen_process: a running Popen process with output to print
         :param stop_func: a Callable that returns True when output streaming
             should stop and the popen_process should be terminated.
-        :param filter_func: a callable that will be invoked on every line
-            of output that is streamed. The function accepts the "raw" line
-            of input (stripped of any trailing newline); it returns a generator
+        :param filter_func: a callable that will be invoked on every line of
+            output that is streamed. The function accepts the "raw" line of
+            input (stripped of any trailing newline); it returns a generator
             that yields the filtered output that should be displayed to the user.
             Can raise StopStreaming to terminate the output stream.
         """

Additionally, if I manually reflow these :param xxx: docs to the 88 char max, docformatter doesn't attempt to shorten them:


class Example:
     def stream_output(
         self,
         label: str,
         popen_process: subprocess.Popen,
         stop_func: Callable[[], bool] = lambda: False,
         filter_func: Callable[[str], Iterator[str]] | None = None,
     ):
         """Stream the output of a Popen process until the process exits. If the user
         sends CTRL+C, the process will be terminated.

-        This is useful for starting a process via Popen such as tailing a
-        log file, then initiating a non-blocking process that populates that
-        log, and finally streaming the original process's output here.
+        This is useful for starting a process via Popen such as tailing a log file, then
+        initiating a non-blocking process that populates that log, and finally streaming
+        the original process's output here.

-        :param label: A description of the content being streamed; used for
-            to provide context in logging messages.
+        :param label: A description of the content being streamed; used for to provide
+            context in logging messages.
         :param popen_process: a running Popen process with output to print
-        :param stop_func: a Callable that returns True when output streaming
-            should stop and the popen_process should be terminated.
-        :param filter_func: a callable that will be invoked on every line
-            of output that is streamed. The function accepts the "raw" line
-            of input (stripped of any trailing newline); it returns a generator
-            that yields the filtered output that should be displayed to the user.
-            Can raise StopStreaming to terminate the output stream.
+        :param stop_func: a Callable that returns True when output streaming should
+            stop and the popen_process should be terminated.
+        :param filter_func: a callable that will be invoked on every line of output
+            that is streamed. The function accepts the "raw" line of input (stripped of
+            any trailing newline); it returns a generator that yields the filtered
+            output that should be displayed to the user. Can raise StopStreaming to
+            terminate the output stream.
         """
weibullguy commented 1 year ago

@rmartin16 should be fixed in v1.7.2-rc5.

rmartin16 commented 1 year ago

Good deal; I'm seeing the examples above now extending the docs for :params xxx: to the specified line length.

Although, it seems it can be a little over-aggressive when compressing in to one line. It appears the underlying problem is only the docs for the parameter are being compared to the line length instead of how long the entire line will become when composed.

class Example:
    def _write_requirements_file(self, app, requires, requirements_path):
        """Configure application requirements by writing a requirements.txt file.

         :param app: The app configuration
         :param requires: The full list of requirements
-        :param requirements_path: The full path to a requirements.txt file that
-            will be written.
+        :param requirements_path: The full path to a requirements.txt file that will be written.
         """
class Example:
    def _build_app(self, app, update, update_requirements, update_resources, update_support, no_update, test_mode, **options):
        """Internal method to invoke a build on a single app. Ensures the app exists,
        and has been updated (if requested) before attempting to issue the actual build
        command.

         :param app: The application to build
         :param update: Should the application be updated before building?
-        :param update_requirements: Should the application requirements be
-            updated before building?
-        :param update_resources: Should the application resources be updated
-            before building?
+        :param update_requirements: Should the application requirements be updated before building?
+        :param update_resources: Should the application resources be updated before building?
         :param update_support: Should the application support be updated?
         :param no_update: Should automated updates be disabled?
         :param test_mode: Is the app being build in test mode?
class Example:
    def update_emulator_config(self, avd, updates):
         """Update the AVD configuration with specific values.

         :params avd: The AVD whose config will be updated
-        :params updates: A dictionary containing the new key-value to
-            add to the device configuration.
+        :params updates: A dictionary containing the new key-value to add to the device configuration.
         """
weibullguy commented 1 year ago

@rmartin16 you were correct, the field name wasn't being accounted for in the length of the line. Should be fixed in v1.7.2-rc6.

rmartin16 commented 1 year ago

That fixes it. Thanks.

weibullguy commented 1 year ago

Closing this issue to #231.