# <!-- rdoc-file=ext/pathname/pathname.c -->
# Pathname represents the name of a file or directory on the filesystem, but not
# the file itself.
#
# The pathname depends on the Operating System: Unix, Windows, etc. This library
# works with pathnames of local OS, however non-Unix pathnames are supported
# experimentally.
#
# A Pathname can be relative or absolute.  It's not until you try to reference
# the file that it even matters whether the file exists or not.
#
# Pathname is immutable.  It has no method for destructive update.
#
# The goal of this class is to manipulate file path information in a neater way
# than standard Ruby provides.  The examples below demonstrate the difference.
#
# **All** functionality from File, FileTest, and some from Dir and FileUtils is
# included, in an unsurprising way.  It is essentially a facade for all of
# these, and more.
#
# ## Examples
#
# ### Example 1: Using Pathname
#
#     require 'pathname'
#     pn = Pathname.new("/usr/bin/ruby")
#     size = pn.size              # 27662
#     isdir = pn.directory?       # false
#     dir  = pn.dirname           # Pathname:/usr/bin
#     base = pn.basename          # Pathname:ruby
#     dir, base = pn.split        # [Pathname:/usr/bin, Pathname:ruby]
#     data = pn.read
#     pn.open { |f| _ }
#     pn.each_line { |line| _ }
#
# ### Example 2: Using standard Ruby
#
#     pn = "/usr/bin/ruby"
#     size = File.size(pn)        # 27662
#     isdir = File.directory?(pn) # false
#     dir  = File.dirname(pn)     # "/usr/bin"
#     base = File.basename(pn)    # "ruby"
#     dir, base = File.split(pn)  # ["/usr/bin", "ruby"]
#     data = File.read(pn)
#     File.open(pn) { |f| _ }
#     File.foreach(pn) { |line| _ }
#
# ### Example 3: Special features
#
#     p1 = Pathname.new("/usr/lib")   # Pathname:/usr/lib
#     p2 = p1 + "ruby/1.8"            # Pathname:/usr/lib/ruby/1.8
#     p3 = p1.parent                  # Pathname:/usr
#     p4 = p2.relative_path_from(p3)  # Pathname:lib/ruby/1.8
#     pwd = Pathname.pwd              # Pathname:/home/gavin
#     pwd.absolute?                   # true
#     p5 = Pathname.new "."           # Pathname:.
#     p5 = p5 + "music/../articles"   # Pathname:music/../articles
#     p5.cleanpath                    # Pathname:articles
#     p5.realpath                     # Pathname:/home/gavin/articles
#     p5.children                     # [Pathname:/home/gavin/articles/linux, ...]
#
# ## Breakdown of functionality
#
# ### Core methods
#
# These methods are effectively manipulating a String, because that's all a path
# is.  None of these access the file system except for #mountpoint?, #children,
# #each_child, #realdirpath and #realpath.
#
# *   +
# *   #join
# *   #parent
# *   #root?
# *   #absolute?
# *   #relative?
# *   #relative_path_from
# *   #each_filename
# *   #cleanpath
# *   #realpath
# *   #realdirpath
# *   #children
# *   #each_child
# *   #mountpoint?
#
#
# ### File status predicate methods
#
# These methods are a facade for FileTest:
# *   #blockdev?
# *   #chardev?
# *   #directory?
# *   #executable?
# *   #executable_real?
# *   #exist?
# *   #file?
# *   #grpowned?
# *   #owned?
# *   #pipe?
# *   #readable?
# *   #world_readable?
# *   #readable_real?
# *   #setgid?
# *   #setuid?
# *   #size
# *   #size?
# *   #socket?
# *   #sticky?
# *   #symlink?
# *   #writable?
# *   #world_writable?
# *   #writable_real?
# *   #zero?
#
#
# ### File property and manipulation methods
#
# These methods are a facade for File:
# *   #atime
# *   #birthtime
# *   #ctime
# *   #mtime
# *   #chmod(mode)
# *   #lchmod(mode)
# *   #chown(owner, group)
# *   #lchown(owner, group)
# *   #fnmatch(pattern, *args)
# *   #fnmatch?(pattern, *args)
# *   #ftype
# *   #make_link(old)
# *   #open(*args, &block)
# *   #readlink
# *   #rename(to)
# *   #stat
# *   #lstat
# *   #make_symlink(old)
# *   #truncate(length)
# *   #utime(atime, mtime)
# *   #basename(*args)
# *   #dirname
# *   #extname
# *   #expand_path(*args)
# *   #split
#
#
# ### Directory methods
#
# These methods are a facade for Dir:
# *   Pathname.glob(*args)
# *   Pathname.getwd / Pathname.pwd
# *   #rmdir
# *   #entries
# *   #each_entry(&block)
# *   #mkdir(*args)
# *   #opendir(*args)
#
#
# ### IO
#
# These methods are a facade for IO:
# *   #each_line(*args, &block)
# *   #read(*args)
# *   #binread(*args)
# *   #readlines(*args)
# *   #sysopen(*args)
# *   #write(*args)
# *   #binwrite(*args)
#
#
# ### Utilities
#
# These methods are a mixture of Find, FileUtils, and others:
# *   #find(&block)
# *   #mkpath
# *   #rmtree
# *   #unlink / #delete
#
#
# ## Method documentation
#
# As the above section shows, most of the methods in Pathname are facades.  The
# documentation for these methods generally just says, for instance, "See
# FileTest.writable?", as you should be familiar with the original method
# anyway, and its documentation (e.g. through `ri`) will contain more
# information.  In some cases, a brief description will follow.
#
class Pathname
  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - getwd()
  # -->
  # Returns the current working directory as a Pathname.
  #
  #     Pathname.getwd
  #         #=> #<Pathname:/home/zzak/projects/ruby>
  #
  # See Dir.getwd.
  #
  def self.getwd: () -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - glob(p1, p2 = v2, p3 = v3)
  # -->
  # Returns or yields Pathname objects.
  #
  #     Pathname.glob("lib/i*.rb")
  #         #=> [#<Pathname:lib/ipaddr.rb>, #<Pathname:lib/irb.rb>]
  #
  # See Dir.glob.
  #
  def self.glob: (String | Array[String] pattern, ?Integer flags) -> Array[Pathname]
               | (String | Array[String] pattern, ?Integer flags) { (Pathname) -> untyped } -> nil

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pwd()
  # -->
  # Returns the current working directory as a Pathname.
  #
  #     Pathname.getwd
  #         #=> #<Pathname:/home/zzak/projects/ruby>
  #
  # See Dir.getwd.
  #
  def self.pwd: () -> Pathname

  public

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - +(other)
  # -->
  # Appends a pathname fragment to `self` to produce a new Pathname object.
  #
  #     p1 = Pathname.new("/usr")      # Pathname:/usr
  #     p2 = p1 + "bin/ruby"           # Pathname:/usr/bin/ruby
  #     p3 = p1 + "/etc/passwd"        # Pathname:/etc/passwd
  #
  #     # / is aliased to +.
  #     p4 = p1 / "bin/ruby"           # Pathname:/usr/bin/ruby
  #     p5 = p1 / "/etc/passwd"        # Pathname:/etc/passwd
  #
  # This method doesn't access the file system; it is pure string manipulation.
  #
  def +: (Pathname | String | _ToStr other) -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - /(other)
  # -->
  #
  alias / +

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - <=>(p1)
  # -->
  # Provides a case-sensitive comparison operator for pathnames.
  #
  #     Pathname.new('/usr') <=> Pathname.new('/usr/bin')
  #         #=> -1
  #     Pathname.new('/usr/bin') <=> Pathname.new('/usr/bin')
  #         #=> 0
  #     Pathname.new('/usr/bin') <=> Pathname.new('/USR/BIN')
  #         #=> 1
  #
  # It will return `-1`, `0` or `1` depending on the value of the left argument
  # relative to the right argument. Or it will return `nil` if the arguments are
  # not comparable.
  #
  def <=>: (Pathname other) -> Integer
         | (untyped other) -> nil

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - ==(p1)
  # -->
  # Compare this pathname with `other`.  The comparison is string-based. Be aware
  # that two different paths (`foo.txt` and `./foo.txt`) can refer to the same
  # file.
  #
  def ==: (untyped) -> bool

  # <!-- rdoc-file=ext/pathname/pathname.c -->
  # Compare this pathname with `other`.  The comparison is string-based. Be aware
  # that two different paths (`foo.txt` and `./foo.txt`) can refer to the same
  # file.
  #
  def ===: (untyped) -> bool

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - absolute?()
  # -->
  # Predicate method for testing whether a path is absolute.
  #
  # It returns `true` if the pathname begins with a slash.
  #
  #     p = Pathname.new('/im/sure')
  #     p.absolute?
  #         #=> true
  #
  #     p = Pathname.new('not/so/sure')
  #     p.absolute?
  #         #=> false
  #
  def absolute?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - ascend() { |self| ... }
  # -->
  # Iterates over and yields a new Pathname object for each element in the given
  # path in ascending order.
  #
  #     Pathname.new('/path/to/some/file.rb').ascend {|v| p v}
  #        #<Pathname:/path/to/some/file.rb>
  #        #<Pathname:/path/to/some>
  #        #<Pathname:/path/to>
  #        #<Pathname:/path>
  #        #<Pathname:/>
  #
  #     Pathname.new('path/to/some/file.rb').ascend {|v| p v}
  #        #<Pathname:path/to/some/file.rb>
  #        #<Pathname:path/to/some>
  #        #<Pathname:path/to>
  #        #<Pathname:path>
  #
  # Returns an Enumerator if no block was given.
  #
  #     enum = Pathname.new("/usr/bin/ruby").ascend
  #       # ... do stuff ...
  #     enum.each { |e| ... }
  #       # yields Pathnames /usr/bin/ruby, /usr/bin, /usr, and /.
  #
  # It doesn't access the filesystem.
  #
  def ascend: () { (Pathname) -> untyped } -> nil
            | () -> Enumerator[Pathname, nil]

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.atime     -> time
  # -->
  # Returns the last access time for the file.
  #
  # See File.atime.
  #
  def atime: () -> Time

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - basename(p1 = v1)
  # -->
  # Returns the last component of the path.
  #
  # See File.basename.
  #
  def basename: (?String | _ToStr suffix) -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.binread([length [, offset]]) -> string
  # -->
  # Returns all the bytes from the file, or the first `N` if specified.
  #
  # See File.binread.
  #
  def binread: (?Integer length, ?Integer offset) -> String

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.binwrite(string, [offset] )   => fixnum
  #   - pathname.binwrite(string, [offset], open_args )   => fixnum
  # -->
  # Writes `contents` to the file, opening it in binary mode.
  #
  # See File.binwrite.
  #
  def binwrite: (String, ?Integer offset, ?mode: Integer | String, ?flags: Integer, ?external_encoding: encoding, ?internal_encoding: encoding, ?encoding: encoding, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?invalid: :replace ?, ?undef: :replace ?, ?replace: String, ?fallback: Hash[String, String] | Proc | Method, ?xml: :text | :attr, ?universal_newline: true, ?cr_newline: true, ?crlf_newline: true) -> Integer

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.birthtime -> time
  # -->
  # Returns the birth time for the file. If the platform doesn't have birthtime,
  # raises NotImplementedError.
  #
  # See File.birthtime.
  #
  def birthtime: () -> Time

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - blockdev?()
  # -->
  # See FileTest.blockdev?.
  #
  def blockdev?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - chardev?()
  # -->
  # See FileTest.chardev?.
  #
  def chardev?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - children(with_directory=true)
  # -->
  # Returns the children of the directory (files and subdirectories, not
  # recursive) as an array of Pathname objects.
  #
  # By default, the returned pathnames will have enough information to access the
  # files. If you set `with_directory` to `false`, then the returned pathnames
  # will contain the filename only.
  #
  # For example:
  #     pn = Pathname("/usr/lib/ruby/1.8")
  #     pn.children
  #         # -> [ Pathname:/usr/lib/ruby/1.8/English.rb,
  #                Pathname:/usr/lib/ruby/1.8/Env.rb,
  #                Pathname:/usr/lib/ruby/1.8/abbrev.rb, ... ]
  #     pn.children(false)
  #         # -> [ Pathname:English.rb, Pathname:Env.rb, Pathname:abbrev.rb, ... ]
  #
  # Note that the results never contain the entries `.` and `..` in the directory
  # because they are not children.
  #
  def children: (?boolish with_directory) -> Array[Pathname]

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.chmod(mode_int)   -> integer
  # -->
  # Changes file permissions.
  #
  # See File.chmod.
  #
  def chmod: (Integer mode_int) -> Integer

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.chown(owner_int, group_int)       -> integer
  # -->
  # Change owner and group of the file.
  #
  # See File.chown.
  #
  def chown: (Integer owner, Integer group) -> Integer

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - cleanpath(consider_symlink=false)
  # -->
  # Returns clean pathname of `self` with consecutive slashes and useless dots
  # removed.  The filesystem is not accessed.
  #
  # If `consider_symlink` is `true`, then a more conservative algorithm is used to
  # avoid breaking symbolic linkages.  This may retain more `..` entries than
  # absolutely necessary, but without accessing the filesystem, this can't be
  # avoided.
  #
  # See Pathname#realpath.
  #
  def cleanpath: (?boolish consider_symlink) -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.ctime     -> time
  # -->
  # Returns the last change time, using directory information, not the file
  # itself.
  #
  # See File.ctime.
  #
  def ctime: () -> Time

  # <!-- rdoc-file=ext/pathname/pathname.c -->
  # Removes a file or directory, using File.unlink if `self` is a file, or
  # Dir.unlink as necessary.
  #
  def delete: () -> Integer

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - descend() { |v| ... }
  # -->
  # Iterates over and yields a new Pathname object for each element in the given
  # path in descending order.
  #
  #     Pathname.new('/path/to/some/file.rb').descend {|v| p v}
  #        #<Pathname:/>
  #        #<Pathname:/path>
  #        #<Pathname:/path/to>
  #        #<Pathname:/path/to/some>
  #        #<Pathname:/path/to/some/file.rb>
  #
  #     Pathname.new('path/to/some/file.rb').descend {|v| p v}
  #        #<Pathname:path>
  #        #<Pathname:path/to>
  #        #<Pathname:path/to/some>
  #        #<Pathname:path/to/some/file.rb>
  #
  # Returns an Enumerator if no block was given.
  #
  #     enum = Pathname.new("/usr/bin/ruby").descend
  #       # ... do stuff ...
  #     enum.each { |e| ... }
  #       # yields Pathnames /, /usr, /usr/bin, and /usr/bin/ruby.
  #
  # It doesn't access the filesystem.
  #
  def descend: () { (Pathname) -> untyped } -> nil
             | () -> Enumerator[Pathname, nil]

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - directory?()
  # -->
  # See FileTest.directory?.
  #
  def directory?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - dirname()
  # -->
  # Returns all but the last component of the path.
  #
  # See File.dirname.
  #
  def dirname: () -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - each_child(with_directory=true, &b)
  # -->
  # Iterates over the children of the directory (files and subdirectories, not
  # recursive).
  #
  # It yields Pathname object for each child.
  #
  # By default, the yielded pathnames will have enough information to access the
  # files.
  #
  # If you set `with_directory` to `false`, then the returned pathnames will
  # contain the filename only.
  #
  #     Pathname("/usr/local").each_child {|f| p f }
  #     #=> #<Pathname:/usr/local/share>
  #     #   #<Pathname:/usr/local/bin>
  #     #   #<Pathname:/usr/local/games>
  #     #   #<Pathname:/usr/local/lib>
  #     #   #<Pathname:/usr/local/include>
  #     #   #<Pathname:/usr/local/sbin>
  #     #   #<Pathname:/usr/local/src>
  #     #   #<Pathname:/usr/local/man>
  #
  #     Pathname("/usr/local").each_child(false) {|f| p f }
  #     #=> #<Pathname:share>
  #     #   #<Pathname:bin>
  #     #   #<Pathname:games>
  #     #   #<Pathname:lib>
  #     #   #<Pathname:include>
  #     #   #<Pathname:sbin>
  #     #   #<Pathname:src>
  #     #   #<Pathname:man>
  #
  # Note that the results never contain the entries `.` and `..` in the directory
  # because they are not children.
  #
  # See Pathname#children
  #
  def each_child: (?boolish with_directory) { (Pathname) -> void } -> Array[Pathname]
                | (?boolish with_directory) -> Enumerator[Pathname, Array[Pathname]]

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - each_entry()
  # -->
  # Iterates over the entries (files and subdirectories) in the directory,
  # yielding a Pathname object for each entry.
  #
  def each_entry: () { (Pathname) -> untyped } -> nil

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - each_filename() { |filename| ... }
  # -->
  # Iterates over each component of the path.
  #
  #     Pathname.new("/usr/bin/ruby").each_filename {|filename| ... }
  #       # yields "usr", "bin", and "ruby".
  #
  # Returns an Enumerator if no block was given.
  #
  #     enum = Pathname.new("/usr/bin/ruby").each_filename
  #       # ... do stuff ...
  #     enum.each { |e| ... }
  #       # yields "usr", "bin", and "ruby".
  #
  def each_filename: () { (String) -> untyped } -> nil
                   | () -> Enumerator[String, nil]

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.each_line {|line| ... }
  #   - pathname.each_line(sep=$/ [, open_args]) {|line| block }     -> nil
  #   - pathname.each_line(limit [, open_args]) {|line| block }      -> nil
  #   - pathname.each_line(sep, limit [, open_args]) {|line| block } -> nil
  #   - pathname.each_line(...)                                      -> an_enumerator
  # -->
  # Iterates over each line in the file and yields a String object for each.
  #
  def each_line: (?String sep, ?Integer limit, ?mode: Integer | String, ?flags: Integer, ?external_encoding: encoding, ?internal_encoding: encoding, ?encoding: encoding, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?chomp: boolish) { (String) -> untyped } -> nil
               | (Integer limit, ?mode: Integer | String, ?flags: Integer, ?external_encoding: encoding, ?internal_encoding: encoding, ?encoding: encoding, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?chomp: boolish) { (String) -> untyped } -> nil
               | (?String sep, ?Integer limit, ?mode: Integer | String, ?flags: Integer, ?external_encoding: encoding, ?internal_encoding: encoding, ?encoding: encoding, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?chomp: boolish) -> Enumerator[String, nil]
               | (Integer limit, ?mode: Integer | String, ?flags: Integer, ?external_encoding: encoding, ?internal_encoding: encoding, ?encoding: encoding, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?chomp: boolish) -> Enumerator[String, nil]

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - empty?()
  # -->
  # Tests the file is empty.
  #
  # See Dir#empty? and FileTest.empty?.
  #
  def empty?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - entries()
  # -->
  # Return the entries (files and subdirectories) in the directory, each as a
  # Pathname object.
  #
  # The results contains just the names in the directory, without any trailing
  # slashes or recursive look-up.
  #
  #     pp Pathname.new('/usr/local').entries
  #     #=> [#<Pathname:share>,
  #     #    #<Pathname:lib>,
  #     #    #<Pathname:..>,
  #     #    #<Pathname:include>,
  #     #    #<Pathname:etc>,
  #     #    #<Pathname:bin>,
  #     #    #<Pathname:man>,
  #     #    #<Pathname:games>,
  #     #    #<Pathname:.>,
  #     #    #<Pathname:sbin>,
  #     #    #<Pathname:src>]
  #
  # The result may contain the current directory `#<Pathname:.>` and the parent
  # directory `#<Pathname:..>`.
  #
  # If you don't want `.` and `..` and want directories, consider
  # Pathname#children.
  #
  def entries: () -> Array[Pathname]

  # <!-- rdoc-file=ext/pathname/pathname.c -->
  # Compare this pathname with `other`.  The comparison is string-based. Be aware
  # that two different paths (`foo.txt` and `./foo.txt`) can refer to the same
  # file.
  #
  def eql?: (untyped) -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - executable?()
  # -->
  # See FileTest.executable?.
  #
  def executable?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - executable_real?()
  # -->
  # See FileTest.executable_real?.
  #
  def executable_real?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - exist?()
  # -->
  # See FileTest.exist?.
  #
  def exist?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - expand_path(p1 = v1)
  # -->
  # Returns the absolute path for the file.
  #
  # See File.expand_path.
  #
  def expand_path: (?String dir) -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - extname()
  # -->
  # Returns the file's extension.
  #
  # See File.extname.
  #
  def extname: () -> String

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - file?()
  # -->
  # See FileTest.file?.
  #
  def file?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - find(ignore_error: true) { |pathname| ... }
  # -->
  # Iterates over the directory tree in a depth first manner, yielding a Pathname
  # for each file under "this" directory.
  #
  # Returns an Enumerator if no block is given.
  #
  # Since it is implemented by the standard library module Find, Find.prune can be
  # used to control the traversal.
  #
  # If `self` is `.`, yielded pathnames begin with a filename in the current
  # directory, not `./`.
  #
  # See Find.find
  #
  def find: (?ignore_error: boolish) { (Pathname) -> untyped } -> nil
          | (?ignore_error: boolish) -> Enumerator[Pathname, nil]

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.fnmatch(pattern, [flags])        -> true or false
  #   - pathname.fnmatch?(pattern, [flags])       -> true or false
  # -->
  # Return `true` if the receiver matches the given pattern.
  #
  # See File.fnmatch.
  #
  def fnmatch: (String pattern, ?Integer flags) -> bool

  # <!-- rdoc-file=ext/pathname/pathname.c -->
  # Return `true` if the receiver matches the given pattern.
  #
  # See File.fnmatch.
  #
  alias fnmatch? fnmatch

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.freeze -> obj
  # -->
  # Freezes this Pathname.
  #
  # See Object.freeze.
  #
  def freeze: () -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.ftype     -> string
  # -->
  # Returns "type" of file ("file", "directory", etc).
  #
  # See File.ftype.
  #
  def ftype: () -> String

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - glob(p1, p2 = v2)
  # -->
  # Returns or yields Pathname objects.
  #
  #     Pathname("ruby-2.4.2").glob("R*.md")
  #     #=> [#<Pathname:ruby-2.4.2/README.md>, #<Pathname:ruby-2.4.2/README.ja.md>]
  #
  # See Dir.glob. This method uses the `base` keyword argument of Dir.glob.
  #
  def glob: (String | Array[String] pattern, ?Integer flags) -> Array[Pathname]
          | (String | Array[String] pattern, ?Integer flags) { (Pathname) -> untyped } -> nil

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - grpowned?()
  # -->
  # See FileTest.grpowned?.
  #
  def grpowned?: () -> bool

  def hash: () -> Integer

  def inspect: () -> String

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - join(*args)
  # -->
  # Joins the given pathnames onto `self` to create a new Pathname object.
  #
  #     path0 = Pathname.new("/usr")                # Pathname:/usr
  #     path0 = path0.join("bin/ruby")              # Pathname:/usr/bin/ruby
  #         # is the same as
  #     path1 = Pathname.new("/usr") + "bin/ruby"   # Pathname:/usr/bin/ruby
  #     path0 == path1
  #         #=> true
  #
  def join: (*String | _ToStr | Pathname args) -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.lchmod(mode_int)  -> integer
  # -->
  # Same as Pathname.chmod, but does not follow symbolic links.
  #
  # See File.lchmod.
  #
  def lchmod: (Integer mode) -> Integer

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.lchown(owner_int, group_int)      -> integer
  # -->
  # Same as Pathname.chown, but does not follow symbolic links.
  #
  # See File.lchown.
  #
  def lchown: (Integer owner, Integer group) -> Integer

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - lstat()
  # -->
  # See File.lstat.
  #
  def lstat: () -> ::File::Stat

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.make_link(old)
  # -->
  # Creates a hard link at *pathname*.
  #
  # See File.link.
  #
  def make_link: (String | Pathname | _ToStr old) -> Integer

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.make_symlink(old)
  # -->
  # Creates a symbolic link.
  #
  # See File.symlink.
  #
  def make_symlink: (String | Pathname | _ToStr old) -> Integer

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - mkdir(p1 = v1)
  # -->
  # Create the referenced directory.
  #
  # See Dir.mkdir.
  #
  def mkdir: (?Integer perm) -> Integer

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - mkpath(mode: nil)
  # -->
  # Creates a full path, including any intermediate directories that don't yet
  # exist.
  #
  # See FileUtils.mkpath and FileUtils.mkdir_p
  #
  def mkpath: () -> nil

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - mountpoint?()
  # -->
  # Returns `true` if `self` points to a mountpoint.
  #
  def mountpoint?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.mtime     -> time
  # -->
  # Returns the last modified time of the file.
  #
  # See File.mtime.
  #
  def mtime: () -> Time

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.open()
  #   - pathname.open(mode="r" [, opt])                        -> file
  #   - pathname.open([mode [, perm]] [, opt])                 -> file
  #   - pathname.open(mode="r" [, opt]) {|file| block }        -> obj
  #   - pathname.open([mode [, perm]] [, opt]) {|file| block } -> obj
  # -->
  # Opens the file for reading or writing.
  #
  # See File.open.
  #
  def open: (?string | int mode, ?int perm) -> File
          | [T] (?string | int mode, ?int perm) { (File) -> T } -> T

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - opendir()
  # -->
  # Opens the referenced directory.
  #
  # See Dir.open.
  #
  def opendir: () -> Dir
             | [U] () { (Dir) -> U } -> U

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - owned?()
  # -->
  # See FileTest.owned?.
  #
  def owned?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - parent()
  # -->
  # Returns the parent directory.
  #
  # This is same as `self + '..'`.
  #
  def parent: () -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pipe?()
  # -->
  # See FileTest.pipe?.
  #
  def pipe?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.read([length [, offset]]) -> string
  #   - pathname.read([length [, offset]], open_args) -> string
  # -->
  # Returns all data from the file, or the first `N` bytes if specified.
  #
  # See File.read.
  #
  def read: (?Integer length, ?Integer offset, ?mode: Integer | String, ?flags: Integer, ?external_encoding: encoding, ?internal_encoding: encoding, ?encoding: encoding, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish) -> String

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - readable?()
  # -->
  # See FileTest.readable?.
  #
  def readable?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - readable_real?()
  # -->
  # See FileTest.readable_real?.
  #
  def readable_real?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.readlines(sep=$/ [, open_args])     -> array
  #   - pathname.readlines(limit [, open_args])      -> array
  #   - pathname.readlines(sep, limit [, open_args]) -> array
  # -->
  # Returns all the lines from the file.
  #
  # See File.readlines.
  #
  def readlines: (?String sep, ?Integer limit, ?mode: Integer | String, ?flags: Integer, ?external_encoding: encoding, ?internal_encoding: encoding, ?encoding: encoding, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?chomp: boolish) -> Array[String]
               | (Integer limit, ?mode: Integer | String, ?flags: Integer, ?external_encoding: encoding, ?internal_encoding: encoding, ?encoding: encoding, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish, ?chomp: boolish) -> Array[String]

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - readlink()
  # -->
  # Read symbolic link.
  #
  # See File.readlink.
  #
  def readlink: () -> untyped

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - realdirpath(p1 = v1)
  # -->
  # Returns the real (absolute) pathname of `self` in the actual filesystem.
  #
  # Does not contain symlinks or useless dots, `..` and `.`.
  #
  # The last component of the real pathname can be nonexistent.
  #
  def realdirpath: (?string | Pathname base_dir) -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - realpath(p1 = v1)
  # -->
  # Returns the real (absolute) pathname for `self` in the actual filesystem.
  #
  # Does not contain symlinks or useless dots, `..` and `.`.
  #
  # All components of the pathname must exist when this method is called.
  #
  def realpath: (?string | Pathname base_dir) -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - relative?()
  # -->
  # The opposite of Pathname#absolute?
  #
  # It returns `false` if the pathname begins with a slash.
  #
  #     p = Pathname.new('/im/sure')
  #     p.relative?
  #         #=> false
  #
  #     p = Pathname.new('not/so/sure')
  #     p.relative?
  #         #=> true
  #
  def relative?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - relative_path_from(base_directory)
  # -->
  # Returns a relative path from the given `base_directory` to the receiver.
  #
  # If `self` is absolute, then `base_directory` must be absolute too.
  #
  # If `self` is relative, then `base_directory` must be relative too.
  #
  # This method doesn't access the filesystem.  It assumes no symlinks.
  #
  # ArgumentError is raised when it cannot find a relative path.
  #
  # Note that this method does not handle situations where the case sensitivity of
  # the filesystem in use differs from the operating system default.
  #
  def relative_path_from: (Pathname | string base_directory) -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - rename(p1)
  # -->
  # Rename the file.
  #
  # See File.rename.
  #
  def rename: (Pathname | string new_name) -> 0

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - rmdir()
  # -->
  # Remove the referenced directory.
  #
  # See Dir.rmdir.
  #
  def rmdir: () -> 0

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - rmtree()
  # -->
  # Recursively deletes a directory, including all directories beneath it.
  #
  # See FileUtils.rm_r
  #
  def rmtree: () -> void

  # <!--
  #   rdoc-file=ext/pathname/lib/pathname.rb
  #   - root?()
  # -->
  # Predicate method for root directories.  Returns `true` if the pathname
  # consists of consecutive slashes.
  #
  # It doesn't access the filesystem.  So it may return `false` for some pathnames
  # which points to roots such as `/usr/..`.
  #
  def root?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - setgid?()
  # -->
  # See FileTest.setgid?.
  #
  def setgid?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - setuid?()
  # -->
  # See FileTest.setuid?.
  #
  def setuid?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - size()
  # -->
  # See FileTest.size.
  #
  def size: () -> Integer

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - size?()
  # -->
  # See FileTest.size?.
  #
  def size?: () -> Integer?

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - socket?()
  # -->
  # See FileTest.socket?.
  #
  def socket?: () -> untyped

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - split()
  # -->
  # Returns the #dirname and the #basename in an Array.
  #
  # See File.split.
  #
  def split: () -> [ Pathname, Pathname ]

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - stat()
  # -->
  # Returns a File::Stat object.
  #
  # See File.stat.
  #
  def stat: () -> File::Stat

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - sticky?()
  # -->
  # See FileTest.sticky?.
  #
  def sticky?: () -> untyped

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - sub(*args)
  # -->
  # Return a pathname which is substituted by String#sub.
  #
  #     path1 = Pathname.new('/usr/bin/perl')
  #     path1.sub('perl', 'ruby')
  #         #=> #<Pathname:/usr/bin/ruby>
  #
  def sub: (Regexp | string pattern, string | Hash[String, String] replacement) -> Pathname
         | (Regexp | string pattern) { (String match) -> string } -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - sub_ext(p1)
  # -->
  # Return a pathname with `repl` added as a suffix to the basename.
  #
  # If self has no extension part, `repl` is appended.
  #
  #     Pathname.new('/usr/bin/shutdown').sub_ext('.rb')
  #         #=> #<Pathname:/usr/bin/shutdown.rb>
  #
  def sub_ext: (string replacement) -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - symlink?()
  # -->
  # See FileTest.symlink?.
  #
  def symlink?: () -> untyped

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.sysopen([mode, [perm]])  -> fixnum
  # -->
  # See IO.sysopen.
  #
  def sysopen: (?String mode, ?Integer perm) -> Integer

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.taint -> obj
  # -->
  # Returns pathname.  This method is deprecated and will be removed in Ruby 3.2.
  #
  def taint: () -> Pathname

  # <!-- rdoc-file=ext/pathname/pathname.c -->
  # Return the path as a String.
  #
  # to_path is implemented so Pathname objects are usable with File.open, etc.
  #
  def to_path: () -> String

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.to_s             -> string
  #   - pathname.to_path          -> string
  # -->
  # Return the path as a String.
  #
  # to_path is implemented so Pathname objects are usable with File.open, etc.
  #
  alias to_s to_path

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - truncate(p1)
  # -->
  # Truncates the file to `length` bytes.
  #
  # See File.truncate.
  #
  def truncate: (Integer length) -> 0

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - unlink()
  # -->
  # Removes a file or directory, using File.unlink if `self` is a file, or
  # Dir.unlink as necessary.
  #
  def unlink: () -> Integer

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.untaint -> obj
  # -->
  # Returns pathname.  This method is deprecated and will be removed in Ruby 3.2.
  #
  def untaint: () -> Pathname

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - utime(p1, p2)
  # -->
  # Update the access and modification times of the file.
  #
  # See File.utime.
  #
  def utime: (Integer | Time atime, Integer | Time mtime) -> Integer

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - world_readable?()
  # -->
  # See FileTest.world_readable?.
  #
  def world_readable?: () -> (Integer | nil)

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - world_writable?()
  # -->
  # See FileTest.world_writable?.
  #
  def world_writable?: () -> (Integer | nil)

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - writable?()
  # -->
  # See FileTest.writable?.
  #
  def writable?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - writable_real?()
  # -->
  # See FileTest.writable_real?.
  #
  def writable_real?: () -> bool

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - pathname.write(string, [offset] )   => fixnum
  #   - pathname.write(string, [offset], open_args )   => fixnum
  # -->
  # Writes `contents` to the file.
  #
  # See File.write.
  #
  def write: (String content, ?Integer offset, ?mode: Integer | String, ?flags: Integer, ?external_encoding: encoding, ?internal_encoding: encoding, ?encoding: encoding, ?textmode: boolish, ?binmode: boolish, ?autoclose: boolish) -> Integer

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - zero?()
  # -->
  # See FileTest.zero?.
  #
  def zero?: () -> bool

  private

  def add_trailing_separator: (untyped path) -> untyped

  def chop_basename: (untyped path) -> untyped

  def cleanpath_aggressive: () -> untyped

  def cleanpath_conservative: () -> untyped

  def del_trailing_separator: (untyped path) -> untyped

  def has_trailing_separator?: (untyped path) -> untyped

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - new(p1)
  # -->
  # Create a Pathname object from the given String (or String-like object). If
  # `path` contains a NULL character (`\0`), an ArgumentError is raised.
  #
  def initialize: (string | Pathname) -> void

  def plus: (untyped path1, untyped path2) -> untyped

  def prepend_prefix: (untyped prefix, untyped relpath) -> untyped

  def split_names: (untyped path) -> untyped

  SAME_PATHS: Proc

  SEPARATOR_LIST: String

  SEPARATOR_PAT: Regexp

  TO_PATH: Symbol
end

%a{annotate:rdoc:skip}
module Kernel
  private

  # <!--
  #   rdoc-file=ext/pathname/pathname.c
  #   - Pathname(path)  -> pathname
  # -->
  # Creates a new Pathname object from the given string, `path`, and returns
  # pathname object.
  #
  # In order to use this constructor, you must first require the Pathname standard
  # library extension.
  #
  #     require 'pathname'
  #     Pathname("/home/zzak")
  #     #=> #<Pathname:/home/zzak>
  #
  # See also Pathname::new for more information.
  #
  def self?.Pathname: (String | Pathname) -> Pathname
end
