It looks like the xrootd client does not want them urlencoded, at least that's my guess looking at the debug output line right after "Seckrb5: getCredentials".
[adrian@blackhole:~ $]> XrdSecDEBUG=1 KRB5CCNAME=FILE:/dev/null python -c "from xrootdpyfs import XRootDPyFS; print XRootDPyFS('root://eospublic.cern.ch//', {'xrd.wantprot': 'krb5', 'xrd.k5ccname': 'FILE:/tmp/krb5cc_1000'})._client.ping()"
sec_Client: protocol request for host eospublic.cern.ch token='&P=krb5,host/eospublic-srv-m2.cern.ch@CERN.CH&P=gsi,v:10300,c:ssl,ca:5168735f.0|4339b4bc.0&P=unix&P=sss,0.13:/etc/eos.keytab'
sec_PM: Loaded krb5 protocol object from libXrdSeckrb5.so
sec_PM: Using krb5 protocol, args='host/eospublic-srv-m2.cern.ch@CERN.CH'
Seckrb5: getCredentials
Seckrb5: FILE%3A%2Ftmp%2Fkrb5cc_1000
Seckrb5: init context
Seckrb5: cc set default name
Seckrb5: cc default
Seckrb5: context lock
Seckrb5: context locked
Seckrb5: get_krbCreds: err copying client name to creds; No credentials cache found
sec_Client: protocol request for host eospublic.cern.ch token='&P=gsi,v:10300,c:ssl,ca:5168735f.0|4339b4bc.0&P=unix&P=sss,0.13:/etc/eos.keytab'
sec_PM: Skipping gsi only want krb5
sec_PM: Skipping unix only want krb5
sec_PM: Skipping sss only want krb5
(<status: 3, code: 204, ok: False, errno: 0, error: True, message: '[FATAL] Auth failed', fatal: True, shellcode: 52>, None)
After changing the query string generation to '&'.join('{0}={1}'.format(*x) for x in self.queryargs.items()), auth seems to work fine:
[adrian@blackhole:~ $]> XrdSecDEBUG=1 KRB5CCNAME=FILE:/dev/null python -c "from xrootdpyfs import XRootDPyFS; print XRootDPyFS('root://eospublic.cern.ch//', {'xrd.wantprot': 'krb5', 'xrd.k5ccname': 'FILE:/tmp/krb5cc_1000'})._client.ping()"
sec_Client: protocol request for host eospublic.cern.ch token='&P=krb5,host/eospublic-srv-m2.cern.ch@CERN.CH&P=gsi,v:10300,c:ssl,ca:5168735f.0|4339b4bc.0&P=unix&P=sss,0.13:/etc/eos.keytab'
sec_PM: Loaded krb5 protocol object from libXrdSeckrb5.so
sec_PM: Using krb5 protocol, args='host/eospublic-srv-m2.cern.ch@CERN.CH'
Seckrb5: getCredentials
Seckrb5: FILE:/tmp/krb5cc_1000
Seckrb5: init context
Seckrb5: cc set default name
Seckrb5: cc default
Seckrb5: context lock
Seckrb5: context locked
Seckrb5: Returned 2637 bytes of creds; p=host/eospublic-srv-m2.cern.ch@CERN.CH
(<status: 0, code: 0, ok: True, errno: 0, error: False, message: '[SUCCESS] ', fatal: False, shellcode: 0>, None)
It looks like the xrootd client does not want them urlencoded, at least that's my guess looking at the debug output line right after "Seckrb5: getCredentials".
After changing the query string generation to
'&'.join('{0}={1}'.format(*x) for x in self.queryargs.items()), auth seems to work fine: