googleapis / google-cloud-ruby

Google Cloud Client Library for Ruby
https://googleapis.github.io/google-cloud-ruby/
Apache License 2.0
1.35k stars 546 forks source link

Exception when pretty printing generated configuration objects #23536

Open dentarg opened 11 months ago

dentarg commented 11 months ago

Environment details

$ gem list google-cloud-

*** LOCAL GEMS ***

google-cloud-common (1.3.0)
google-cloud-compute (1.2.0)
google-cloud-compute-v1 (2.5.0)
google-cloud-core (1.6.0)
google-cloud-env (1.6.0)
google-cloud-error_reporting (0.42.3, 0.42.2)
google-cloud-error_reporting-v1beta1 (0.8.0, 0.6.0)
google-cloud-errors (1.3.1)
google-cloud-logging (2.3.3, 2.3.2)
google-cloud-logging-v2 (0.11.0, 0.8.1)
google-cloud-pubsub (2.15.1)
google-cloud-pubsub-v1 (0.15.1)
google-cloud-storage (1.44.0)
google-cloud-trace (0.42.2, 0.42.1)
google-cloud-trace-v1 (0.7.0, 0.5.0)
google-cloud-trace-v2 (0.7.0, 0.5.0)

Steps to reproduce

require tempfile and try to pretty print (pp) the client object

Code example

credentials.json is the standard key file:

{
  "type": "service_account",
  "project_id": "patrik-testing",
  "private_key_id": "REDACTED",
  "private_key": "REDACTED",
  "client_email": "REDACTED",
  "client_id": "REDACTED",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/REDACTED",
  "universe_domain": "googleapis.com"
}

Run this

COMPUTE_CREDENTIALS=credentials.json ruby -rtempfile -rgoogle/cloud/compute -e 'pp Google::Cloud::Compute.accelerator_types'

Full backtrace

$ COMPUTE_CREDENTIALS=credentials.json ruby -rtempfile -rgoogle/cloud/compute -e 'pp Google::Cloud::Compute.accelerator_types'
#<Google::Cloud::Compute::V1::AcceleratorTypes::Rest::Client:0x00000001098d10d0
 @accelerator_types_stub=
  #<Google::Cloud::Compute::V1::AcceleratorTypes::Rest::ServiceStub:0x0000000109e18ef8
   @client_stub=
    #<Gapic::Rest::ClientStub:0x0000000109d97a88
     @connection=
      #<Faraday::Connection:0x00000001088406f8
       @builder=
        #<Faraday::RackBuilder:0x0000000109e189a8
         @adapter=Faraday::Adapter::NetHttp,
         @handlers=[Gapic::Rest::FaradayMiddleware::GoogleAuthorization, Faraday::Retry::Middleware, Faraday::Response::RaiseError]>,
       @default_parallel_manager=nil,
       @headers={"Content-Type"=>"application/json", "User-Agent"=>"Faraday v2.7.11"},
       @manual_proxy=false,
       @options=
        #<struct Faraday::RequestOptions
         params_encoder=nil,
         proxy=nil,
         bind=nil,
         timeout=nil,
         open_timeout=nil,
         read_timeout=nil,
         write_timeout=nil,
         boundary=nil,
         oauth=nil,
         context=nil,
         on_data=nil>,
       @parallel_manager=nil,
       @params={},
       @proxy=nil,
       @ssl=
        #<struct Faraday::SSLOptions
         verify=true,
         verify_hostname=nil,
         ca_file=nil,
         ca_path=nil,
         verify_mode=nil,
         cert_store=nil,
         client_cert=nil,
         client_key=nil,
         certificate=nil,
         private_key=nil,
         verify_depth=nil,
         version=nil,
         min_version=nil,
         max_version=nil>,
       @url_prefix=#<URI::HTTPS https://compute.googleapis.com/>>,
     @credentials=
      #<Google::Cloud::Compute::V1::AcceleratorTypes::Credentials:0x0000000109491060
       @client=
        #<Google::Auth::ServiceAccountCredentials:0x0000000108edd218
         @access_token=
          "REDACTED",
         @access_type=:offline,
         @additional_parameters={},
         @audience="https://oauth2.googleapis.com/token",
         @authorization_uri=nil,
         @client_id=nil,
         @client_secret=nil,
         @code=nil,
         @connection_info=nil,
         @enable_self_signed_jwt=true,
         @expires_at=2023-11-10 13:56:56.093852 +0100,
         @expiry=60,
         @extension_parameters={},
         @grant_type=nil,
         @granted_scopes=nil,
         @issued_at=2023-11-10 12:56:57.093852 +0100,
         @issuer="REDACTED",
         @password=nil,
         @principal=nil,
         @project_id="patrik-testing",
         @quota_project_id=nil,
         @redirect_uri=nil,
         @refresh_token=nil,
         @scope=["https://www.googleapis.com/auth/compute.readonly", "https://www.googleapis.com/auth/compute", "https://www.googleapis.com/auth/cloud-platform"],
         @signing_key=#<OpenSSL::PKey::RSA:0x00000001099d5cb0 oid=rsaEncryption>,
         @state=nil,
         @target_audience=nil,
         @token_credential_uri=#<Addressable::URI:0x2a8 URI:https://oauth2.googleapis.com/token>,
         @username=nil>,
       @env_vars=nil,
       @paths=nil,
       @project_id="patrik-testing",
       @quota_project_id=nil,
       @scope=nil>,
     @endpoint="https://compute.googleapis.com",
     @numeric_enums=false,
     @raise_faraday_errors=false>>,
 @config=
  #<Google::Cloud::Compute::V1::AcceleratorTypes::Rest::Client::Configuration:0x00000001098d00e0
   @parent_config=/Users/dentarg/.rubies/3.2.2/lib/ruby/gems/3.2.0/gems/google-cloud-core-1.6.0/lib/google/cloud/config.rb:460:in `method_missing': undefined method `is_a?' for <Config: endpoint="compute.googleapis.com" credentials=nil scope=nil lib_name=nil lib_version=nil timeout=nil metadata=nil retry_policy=nil quota_project=nil>:Google::Cloud::Config (NoMethodError)
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:188:in `pp'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:274:in `block (3 levels) in pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:253:in `block (2 levels) in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:280:in `nest'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:252:in `block in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:265:in `group_sub'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:251:in `group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:272:in `block (2 levels) in pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:260:in `block in seplist'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:254:in `each'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:254:in `seplist'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:267:in `block in pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:253:in `block (2 levels) in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:280:in `nest'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:252:in `block in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:265:in `group_sub'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:251:in `group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:215:in `object_address_group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:266:in `pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:328:in `pretty_print'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:197:in `block in pp'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:253:in `block (2 levels) in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:280:in `nest'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:252:in `block in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:265:in `group_sub'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:251:in `group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:197:in `pp'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:274:in `block (3 levels) in pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:253:in `block (2 levels) in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:280:in `nest'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:252:in `block in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:265:in `group_sub'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:251:in `group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:272:in `block (2 levels) in pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:260:in `block in seplist'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:254:in `each'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:254:in `seplist'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:267:in `block in pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:253:in `block (2 levels) in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:280:in `nest'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:252:in `block in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:265:in `group_sub'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:251:in `group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:215:in `object_address_group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:266:in `pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:328:in `pretty_print'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:197:in `block in pp'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:253:in `block (2 levels) in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:280:in `nest'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:252:in `block in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:265:in `group_sub'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:251:in `group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:197:in `pp'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:274:in `block (3 levels) in pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:253:in `block (2 levels) in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:280:in `nest'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:252:in `block in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:265:in `group_sub'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:251:in `group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:272:in `block (2 levels) in pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:260:in `block in seplist'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:254:in `each'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:254:in `seplist'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:267:in `block in pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:253:in `block (2 levels) in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:280:in `nest'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:252:in `block in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:265:in `group_sub'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:251:in `group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:215:in `object_address_group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:266:in `pp_object'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:328:in `pretty_print'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:197:in `block in pp'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:253:in `block (2 levels) in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:280:in `nest'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:252:in `block in group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:265:in `group_sub'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/prettyprint.rb:251:in `group'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:197:in `pp'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:93:in `block in pp'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:154:in `guard_inspect_key'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:93:in `pp'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:646:in `block in pp'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:645:in `each'
  from /Users/dentarg/.rubies/3.2.2/lib/ruby/3.2.0/pp.rb:645:in `pp'
  from -e:1:in `<main>'
dentarg commented 11 months ago

Reproduces with both these versions:

$ gem list tempfile

*** LOCAL GEMS ***

tempfile (0.2.0, default: 0.1.3)
dazuma commented 10 months ago

Reproduced, even if tempfile is not present. Looks like pp walks the object graph and calls is_a? on each node, but a client's configuration object is a BasicObject that doesn't implement is_a?, hence the exception.

This may be fixable by customizing pp (e.g. defining #pretty_print) for the config class.