Index: src/wp-includes/media.php
===================================================================
--- src/wp-includes/media.php	(revision 55419)
+++ src/wp-includes/media.php	(working copy)
@@ -175,10 +175,11 @@
  * elements that are normally returned from the function.
  *
  * @since 2.5.0
+ * @since 6.3.0 Allow WP_Post object to be passed.
  *
- * @param int          $id   Attachment ID for image.
- * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array
- *                           of width and height values in pixels (in that order). Default 'medium'.
+ * @param int|WP_Post  $attachment Attachment post object or attachment ID for image.
+ * @param string|int[] $size       Optional. Image size. Accepts any registered image size name, or an array
+ *                                 of width and height values in pixels (in that order). Default 'medium'.
  * @return array|false {
  *     Array of image data, or boolean false if no image is available.
  *
@@ -188,9 +189,15 @@
  *     @type bool   $3 Whether the image is a resized image.
  * }
  */
-function image_downsize( $id, $size = 'medium' ) {
-	$is_image = wp_attachment_is_image( $id );
+function image_downsize( $attachment, $size = 'medium' ) {
+	$is_image = wp_attachment_is_image( $attachment );
 
+	// Ensure backward compatibility whenever a WP_Post object is passed.
+	$id = $attachment;
+	if ( is_a( $attachment, 'WP_Post' ) ) {
+		$id = $attachment->ID;
+	}
+
 	/**
 	 * Filters whether to preempt the output of image_downsize().
 	 *
@@ -361,20 +368,27 @@
  * content.
  *
  * @since 2.5.0
+ * @since 6.3.0 Allow WP_Post object to be passed.
  *
- * @param int          $id    Attachment ID.
- * @param string       $alt   Image description for the alt attribute.
- * @param string       $title Image description for the title attribute.
- * @param string       $align Part of the class name for aligning the image.
- * @param string|int[] $size  Optional. Image size. Accepts any registered image size name, or an array of
- *                            width and height values in pixels (in that order). Default 'medium'.
+ * @param int|WP_Post  $attachment Attachment WP_Post object or attachment ID.
+ * @param string       $alt        Image description for the alt attribute.
+ * @param string       $title      Image description for the title attribute.
+ * @param string       $align      Part of the class name for aligning the image.
+ * @param string|int[] $size       Optional. Image size. Accepts any registered image size name, or an array of
+ *                                 width and height values in pixels (in that order). Default 'medium'.
  * @return string HTML IMG element for given image attachment?
  */
-function get_image_tag( $id, $alt, $title, $align, $size = 'medium' ) {
+function get_image_tag( $attachment, $alt, $title, $align, $size = 'medium' ) {
 
-	list( $img_src, $width, $height ) = image_downsize( $id, $size );
+	list( $img_src, $width, $height ) = image_downsize( $attachment, $size );
 	$hwstring                         = image_hwstring( $width, $height );
 
+	// Ensure backward compatibility whenever a WP_Post object is passed.
+	$id = $attachment;
+	if ( is_a( $attachment, 'WP_Post' ) ) {
+		$id = $attachment->ID;
+	}
+
 	$title = $title ? 'title="' . esc_attr( $title ) . '" ' : '';
 
 	$size_class = is_array( $size ) ? implode( 'x', $size ) : $size;
@@ -741,10 +755,11 @@
  * browser scale down the image.
  *
  * @since 2.5.0
+ * @since 6.3.0 Allow WP_Post object to be passed.
  *
- * @param int          $post_id Attachment ID.
- * @param string|int[] $size    Optional. Image size. Accepts any registered image size name, or an array
- *                              of width and height values in pixels (in that order). Default 'thumbnail'.
+ * @param int|WP_Post  $attachment Attachment post object or attachment ID.
+ * @param string|int[] $size       Optional. Image size. Accepts any registered image size name, or an array
+ *                                 of width and height values in pixels (in that order). Default 'thumbnail'.
  * @return array|false {
  *     Array of file relative path, width, and height on success. Additionally includes absolute
  *     path and URL if registered size is passed to `$size` parameter. False on failure.
@@ -756,8 +771,8 @@
  *     @type string $url    URL of image.
  * }
  */
-function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) {
-	$imagedata = wp_get_attachment_metadata( $post_id );
+function image_get_intermediate_size( $attachment, $size = 'thumbnail' ) {
+	$imagedata = wp_get_attachment_metadata( $attachment );
 
 	if ( ! $size || ! is_array( $imagedata ) || empty( $imagedata['sizes'] ) ) {
 		return false;
@@ -828,11 +843,17 @@
 
 	// Include the full filesystem path of the intermediate file.
 	if ( empty( $data['path'] ) && ! empty( $data['file'] ) && ! empty( $imagedata['file'] ) ) {
-		$file_url     = wp_get_attachment_url( $post_id );
+		$file_url     = wp_get_attachment_url( $attachment );
 		$data['path'] = path_join( dirname( $imagedata['file'] ), $data['file'] );
 		$data['url']  = path_join( dirname( $file_url ), $data['file'] );
 	}
 
+	// Ensure backward compatibility whenever a WP_Post object is passed.
+	$attachment_id = $attachment;
+	if ( is_a( $attachment, 'WP_Post' ) ) {
+		$attachment_id = $attachment->ID;
+	}
+
 	/**
 	 * Filters the output of image_get_intermediate_size()
 	 *
@@ -840,13 +861,13 @@
 	 *
 	 * @see image_get_intermediate_size()
 	 *
-	 * @param array        $data    Array of file relative path, width, and height on success. May also include
-	 *                              file absolute path and URL.
-	 * @param int          $post_id The ID of the image attachment.
-	 * @param string|int[] $size    Requested image size. Can be any registered image size name, or
-	 *                              an array of width and height values in pixels (in that order).
+	 * @param array        $data          Array of file relative path, width, and height on success. May also include
+	 *                                    file absolute path and URL.
+	 * @param int          $attachment_id The ID of the image attachment.
+	 * @param string|int[] $size          Requested image size. Can be any registered image size name, or
+	 *                                    an array of width and height values in pixels (in that order).
 	 */
-	return apply_filters( 'image_get_intermediate_size', $data, $post_id, $size );
+	return apply_filters( 'image_get_intermediate_size', $data, $attachment_id, $size );
 }
 
 /**
@@ -935,11 +956,12 @@
  * Retrieves an image to represent an attachment.
  *
  * @since 2.5.0
+ * @since 6.3.0 Allow WP_Post object to be passed.
  *
- * @param int          $attachment_id Image attachment ID.
- * @param string|int[] $size          Optional. Image size. Accepts any registered image size name, or an array of
- *                                    width and height values in pixels (in that order). Default 'thumbnail'.
- * @param bool         $icon          Optional. Whether the image should fall back to a mime type icon. Default false.
+ * @param int|WP_Post  $attachment Image attachment WP_Post object or attachment ID.
+ * @param string|int[] $size       Optional. Image size. Accepts any registered image size name, or an array of
+ *                                 width and height values in pixels (in that order). Default 'thumbnail'.
+ * @param bool         $icon       Optional. Whether the image should fall back to a mime type icon. Default false.
  * @return array|false {
  *     Array of image data, or boolean false if no image is available.
  *
@@ -949,9 +971,16 @@
  *     @type bool   $3 Whether the image is a resized image.
  * }
  */
-function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon = false ) {
+function wp_get_attachment_image_src( $attachment, $size = 'thumbnail', $icon = false ) {
 	// Get a thumbnail or intermediate image if there is one.
-	$image = image_downsize( $attachment_id, $size );
+	$image = image_downsize( $attachment, $size );
+
+	// Ensure backward compatibility whenever a WP_Post object is passed.
+	$attachment_id = $attachment;
+	if ( is_a( $attachment, 'WP_Post' ) ) {
+		$attachment_id = $attachment->ID;
+	}
+
 	if ( ! $image ) {
 		$src = false;
 
@@ -1004,11 +1033,12 @@
  * @since 4.4.0 The `$srcset` and `$sizes` attributes were added.
  * @since 5.5.0 The `$loading` attribute was added.
  * @since 6.1.0 The `$decoding` attribute was added.
+ * @since 6.3.0 Allow WP_Post object to be passed.
  *
- * @param int          $attachment_id Image attachment ID.
- * @param string|int[] $size          Optional. Image size. Accepts any registered image size name, or an array
- *                                    of width and height values in pixels (in that order). Default 'thumbnail'.
- * @param bool         $icon          Optional. Whether the image should be treated as an icon. Default false.
+ * @param int|WP_Post  $attachment Image attachment WP_Post object or attachment ID.
+ * @param string|int[] $size       Optional. Image size. Accepts any registered image size name, or an array
+ *                                 of width and height values in pixels (in that order). Default 'thumbnail'.
+ * @param bool         $icon       Optional. Whether the image should be treated as an icon. Default false.
  * @param string|array $attr {
  *     Optional. Attributes for the image markup.
  *
@@ -1028,16 +1058,23 @@
  * }
  * @return string HTML img element or empty string on failure.
  */
-function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = false, $attr = '' ) {
+function wp_get_attachment_image( $attachment, $size = 'thumbnail', $icon = false, $attr = '' ) {
 	$html  = '';
-	$image = wp_get_attachment_image_src( $attachment_id, $size, $icon );
+	$image = wp_get_attachment_image_src( $attachment, $size, $icon );
 
+	// Ensure backward compatibility whenever a WP_Post object is passed.
+	$attachment_id = $attachment;
+	if ( is_a( $attachment, 'WP_Post' ) ) {
+		$attachment_id = $attachment->ID;
+	}
+
 	if ( $image ) {
 		list( $src, $width, $height ) = $image;
 
-		$attachment = get_post( $attachment_id );
-		$hwstring   = image_hwstring( $width, $height );
-		$size_class = $size;
+		$attachment    = get_post( $attachment );
+		$attachment_id = ( $attachment ) ? $attachment->ID : 0;
+		$hwstring      = image_hwstring( $width, $height );
+		$size_class    = $size;
 
 		if ( is_array( $size_class ) ) {
 			$size_class = implode( 'x', $size_class );
@@ -1070,12 +1107,12 @@
 
 		// Generate 'srcset' and 'sizes' if not already present.
 		if ( empty( $attr['srcset'] ) ) {
-			$image_meta = wp_get_attachment_metadata( $attachment_id );
+			$image_meta = wp_get_attachment_metadata( $attachment );
 
 			if ( is_array( $image_meta ) ) {
 				$size_array = array( absint( $width ), absint( $height ) );
-				$srcset     = wp_calculate_image_srcset( $size_array, $src, $image_meta, $attachment_id );
-				$sizes      = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment_id );
+				$srcset     = wp_calculate_image_srcset( $size_array, $src, $image_meta, $attachment );
+				$sizes      = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment );
 
 				if ( $srcset && ( $sizes || ! empty( $attr['sizes'] ) ) ) {
 					$attr['srcset'] = $srcset;
@@ -1205,18 +1242,19 @@
  * Retrieves the value for an image attachment's 'srcset' attribute.
  *
  * @since 4.4.0
+ * @since 6.3.0 Allow WP_Post object to be passed.
  *
  * @see wp_calculate_image_srcset()
  *
- * @param int          $attachment_id Image attachment ID.
- * @param string|int[] $size          Optional. Image size. Accepts any registered image size name, or an array of
- *                                    width and height values in pixels (in that order). Default 'medium'.
- * @param array        $image_meta    Optional. The image meta data as returned by 'wp_get_attachment_metadata()'.
- *                                    Default null.
+ * @param int|WP_Post  $attachment Image attachment ID.
+ * @param string|int[] $size       Optional. Image size. Accepts any registered image size name, or an array of
+ *                                 width and height values in pixels (in that order). Default 'medium'.
+ * @param array        $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'.
+ *                                 Default null.
  * @return string|false A 'srcset' value string or false.
  */
-function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) {
-	$image = wp_get_attachment_image_src( $attachment_id, $size );
+function wp_get_attachment_image_srcset( $attachment, $size = 'medium', $image_meta = null ) {
+	$image = wp_get_attachment_image_src( $attachment, $size );
 
 	if ( ! $image ) {
 		return false;
@@ -1223,7 +1261,7 @@
 	}
 
 	if ( ! is_array( $image_meta ) ) {
-		$image_meta = wp_get_attachment_metadata( $attachment_id );
+		$image_meta = wp_get_attachment_metadata( $attachment );
 	}
 
 	$image_src  = $image[0];
@@ -1232,6 +1270,12 @@
 		absint( $image[2] ),
 	);
 
+	// Ensure backward compatibility whenever a WP_Post object is passed.
+	$attachment_id = $attachment;
+	if ( is_a( $attachment, 'WP_Post' ) ) {
+		$attachment_id = $attachment->ID;
+	}
+
 	return wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id );
 }
 
@@ -1446,18 +1490,19 @@
  * Retrieves the value for an image attachment's 'sizes' attribute.
  *
  * @since 4.4.0
+ * @since 6.3.0 Allow WP_Post object to be passed.
  *
  * @see wp_calculate_image_sizes()
  *
- * @param int          $attachment_id Image attachment ID.
- * @param string|int[] $size          Optional. Image size. Accepts any registered image size name, or an array of
- *                                    width and height values in pixels (in that order). Default 'medium'.
- * @param array        $image_meta    Optional. The image meta data as returned by 'wp_get_attachment_metadata()'.
- *                                    Default null.
+ * @param int|WP_Post  $attachment Image attachment post object or attachment ID.
+ * @param string|int[] $size       Optional. Image size. Accepts any registered image size name, or an array of
+ *                                 width and height values in pixels (in that order). Default 'medium'.
+ * @param array        $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'.
+ *                                 Default null.
  * @return string|false A valid source size value for use in a 'sizes' attribute or false.
  */
-function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image_meta = null ) {
-	$image = wp_get_attachment_image_src( $attachment_id, $size );
+function wp_get_attachment_image_sizes( $attachment, $size = 'medium', $image_meta = null ) {
+	$image = wp_get_attachment_image_src( $attachment, $size );
 
 	if ( ! $image ) {
 		return false;
@@ -1464,7 +1509,7 @@
 	}
 
 	if ( ! is_array( $image_meta ) ) {
-		$image_meta = wp_get_attachment_metadata( $attachment_id );
+		$image_meta = wp_get_attachment_metadata( $attachment );
 	}
 
 	$image_src  = $image[0];
@@ -1473,6 +1518,12 @@
 		absint( $image[2] ),
 	);
 
+	// Ensure backward compatibility whenever a WP_Post object is passed.
+	$attachment_id = $attachment;
+	if ( is_a( $attachment, 'WP_Post' ) ) {
+		$attachment_id = $attachment->ID;
+	}
+
 	return wp_calculate_image_sizes( $size_array, $image_src, $image_meta, $attachment_id );
 }
 
Index: src/wp-includes/post.php
===================================================================
--- src/wp-includes/post.php	(revision 55419)
+++ src/wp-includes/post.php	(working copy)
@@ -6510,9 +6510,10 @@
  *
  * @since 2.1.0
  * @since 6.0.0 The `$filesize` value was added to the returned array.
+ * @since 6.3.0 allow WP_Post object to be passed.
  *
- * @param int  $attachment_id Attachment post ID. Defaults to global $post.
- * @param bool $unfiltered    Optional. If true, filters are not run. Default false.
+ * @param int|WP_Post $attachment Attachment post object or attachment ID. Defaults to global $post.
+ * @param bool        $unfiltered Optional. If true, filters are not run. Default false.
  * @return array|false {
  *     Attachment metadata. False on failure.
  *
@@ -6525,9 +6526,14 @@
  *     @type int    $filesize   File size of the attachment.
  * }
  */
-function wp_get_attachment_metadata( $attachment_id = 0, $unfiltered = false ) {
-	$attachment_id = (int) $attachment_id;
+function wp_get_attachment_metadata( $attachment = 0, $unfiltered = false ) {
 
+	if ( is_a( $attachment, 'WP_Post' ) ) {
+		$attachment_id = $attachment->ID;
+	} else {
+		$attachment_id = (int) $attachment;
+	}
+
 	if ( ! $attachment_id ) {
 		$post = get_post();
 
@@ -6597,19 +6603,21 @@
  * Retrieves the URL for an attachment.
  *
  * @since 2.1.0
+ * @since 6.3.0 Allow WP_Post object to be passed.
  *
  * @global string $pagenow The filename of the current screen.
  *
- * @param int $attachment_id Optional. Attachment post ID. Defaults to global $post.
+ * @param int|WP_Post $post Optional. Attachment post object or attachment ID. Defaults to global $post.
  * @return string|false Attachment URL, otherwise false.
  */
-function wp_get_attachment_url( $attachment_id = 0 ) {
+function wp_get_attachment_url( $post = 0 ) {
 	global $pagenow;
 
-	$attachment_id = (int) $attachment_id;
+	if ( ! is_a( $post, 'WP_Post' ) ) {
+		$attachment_id = (int) $post;
+		$post = get_post( $attachment_id );
+	}
 
-	$post = get_post( $attachment_id );
-
 	if ( ! $post ) {
 		return false;
 	}
Index: tests/phpunit/tests/attachment/passedPost.php
===================================================================
--- tests/phpunit/tests/attachment/passedPost.php	(nonexistent)
+++ tests/phpunit/tests/attachment/passedPost.php	(working copy)
@@ -0,0 +1,116 @@
+<?php
+
+/**
+ * @group attachment
+ * @ticket 37255
+ */
+class Tests_Attachment_PassedPost extends WP_UnitTestCase {
+	protected static $a;
+	protected static $a_id;
+
+	public static function wpSetUpBeforeClass() {
+		self::$a_id = self::factory()->attachment->create_upload_object( DIR_TESTDATA . '/images/a2-small.jpg' );
+		self::$a = get_post( self::$a_id );
+	}
+
+	public function test_wp_get_attachment_url_should_accept_post_id() {
+		$str = wp_get_attachment_url( self::$a_id );
+		$this->assertNotEmpty( $str );
+	}
+
+	public function test_wp_get_attachment_url_should_accept_post_object() {
+		$str = wp_get_attachment_url( self::$a );
+		$this->assertNotEmpty( $str );
+	}
+
+	public function test_wp_get_attachment_metadata_should_accept_post_id() {
+		$str = wp_get_attachment_metadata( self::$a_id );
+		$this->assertNotEmpty( $str );
+	}
+
+	public function test_wp_get_attachment_metadata_should_accept_post_object() {
+		$str = wp_get_attachment_metadata( self::$a );
+		$this->assertNotEmpty( $str );
+	}
+
+	public function test_image_downsize_should_accept_post_id() {
+		$arr = image_downsize( self::$a_id );
+		$this->assertNotEmpty( $arr );
+	}
+
+	public function test_image_downsize_should_accept_post_object() {
+		$arr = image_downsize( self::$a );
+		$this->assertNotEmpty( $arr );
+	}
+
+	public function test_get_image_tag_should_accept_post_id() {
+		$html = get_image_tag( self::$a_id, 'foo', 'bar', 'center' );
+		$this->assertNotEmpty( $html );
+	}
+
+	public function test_get_image_tag_should_accept_post_object() {
+		$html = get_image_tag( self::$a, 'foo', 'bar', 'center' );
+		$this->assertNotEmpty( $html );
+	}
+
+	public function test_image_get_intermediate_size_should_accept_post_id() {
+		$arr = image_get_intermediate_size( self::$a_id );
+		$this->assertNotEmpty( $arr );
+	}
+
+	public function test_image_get_intermediate_size_should_accept_post_object() {
+		$arr = image_get_intermediate_size( self::$a );
+		$this->assertNotEmpty( $arr );
+	}
+
+	public function test_wp_get_attachment_image_src_should_accept_post_id() {
+		$arr = wp_get_attachment_image_src( self::$a_id );
+		$this->assertNotEmpty( $arr );
+	}
+
+	public function test_wp_get_attachment_image_src_should_accept_post_object() {
+		$arr = wp_get_attachment_image_src( self::$a );
+		$this->assertNotEmpty( $arr );
+	}
+
+	public function test_wp_get_attachment_image_should_accept_post_id() {
+		$html = wp_get_attachment_image( self::$a_id );
+		$this->assertNotEmpty( $html );
+	}
+
+	public function test_wp_get_attachment_image_should_accept_post_object() {
+		$html = wp_get_attachment_image( self::$a );
+		$this->assertNotEmpty( $html );
+	}
+
+	public function test_wp_get_attachment_image_url_should_accept_post_id() {
+		$str = wp_get_attachment_image_url( self::$a_id );
+		$this->assertNotEmpty( $str );
+	}
+
+	public function test_wp_get_attachment_image_url_should_accept_post_object() {
+		$str = wp_get_attachment_image_url( self::$a );
+		$this->assertNotEmpty( $str );
+	}
+
+	public function test_wp_get_attachment_image_srcset_should_accept_post_id() {
+		$str = wp_get_attachment_image_srcset( self::$a_id );
+		$this->assertNotEmpty( $str );
+	}
+
+	public function test_wp_get_attachment_image_srcset_should_accept_post_object() {
+		$str = wp_get_attachment_image_srcset( self::$a );
+		$this->assertNotEmpty( $str );
+	}
+
+	public function test_wp_get_attachment_image_sizes_should_accept_post_id() {
+		$str = wp_get_attachment_image_sizes( self::$a_id );
+		$this->assertNotEmpty( $str );
+	}
+
+	public function test_wp_get_attachment_image_sizes_should_accept_post_object() {
+		$str = wp_get_attachment_image_sizes( self::$a );
+		$this->assertNotEmpty( $str );
+	}
+
+}
\ No newline at end of file
